WinCC Advanced (flexible): Schaltflächen" entprellen"

faust

Level-2
Beiträge
819
Reaktionspunkte
246
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo in die Runde geballten Wissens,

ich benötige mal Denkanstöße zu einem Problem:

Ich verwende momentan (ein wenig gezwungenermaßen) diverse Siemens-ComfortPanels.
Diese zeichnen sich durch eine solche Performance aus, dass es ein Bediener schafft, eine Schaltfläche, die eigentlich nach Betätigung "gesperrt" ist (ausgeblendet durch Bildwechsel oder überdeckt durch eine scriptgesteuerte Hilfsgrafik), mehrfach zu triggern.
Ich möchte also diese und eigentlich alle Schaltflächen entprellen und so eine ungewollte Mehrfachbetätigung verhindern.

Meine bisherigen Überlegungen sind wie folgt:
1. Boolsche Variable "buttonTriggered" mit Betätigung setzen und diese an "Animation - Bedienbarkeit" projektieren. Rücksetzen dann nach der letzten Ereignis-Funktion, die die Schaltfläche ausführen soll.
2. Wie vor, jedoch blendet "buttonTriggered" eine unsichtbare Schaltfläche VOR der betätigten ein.

Gibt es noch andere Möglichkeiten?


Gruß, Fred
 
Könnte zum entpreellen vielleicht helfen, wenn du dein Ereignis aufrufst,
wenn die Taste losgelassen wird. Das wirkt doch schon fast wie eine entprellung.

Über die Perfomance der neuen Panelreihe schließe ich mich an, mein subjektive
Meinung ist, das diese Panels ganz schön schwach in ihrer Leistung sind.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Könnte zum entpreellen vielleicht helfen, wenn du dein Ereignis aufrufst,
wenn die Taste losgelassen wird. Das wirkt doch schon fast wie eine entprellung.


Dem steht leider die Bediener-Gewohnheit "Ich drücke lange auf die Taste, weil ich ja keine Reaktion sehe" gegenüber. :sad:


Gruß, Fred
 
Beschreib doch mal welche Funktion der Button genau ausführt. VBS-Aktion?

Der Subjektiven Meinung von RN schließe ich mich an.
 
Mir würde jetzt nur noch einfallen, mit den Tastendruck ein Script aufzurufen und das da abzufangen.
Richtiges Entprellen geht ja nur über eine Zeit, dann wirst du im Script eine Zeitschleife einbauen.

Wenn die Variablen zur Steuerungsanbindung und nicht intern genutzt werden, ist es ganz sauber
die Tasten in der Steuerung zu entprellen.

Zeitschleife, du hast mal in irgendeinen Thread geschrieben, das man Zeiten im Script in 'ms' auflösen
kann. Das konnte ich nachvollziehen, kleinste Basis ist meinens erachtens die Sekunde.
Könntes du noch mal darauf eingehen?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Beschreib doch mal welche Funktion der Button genau ausführt. VBS-Aktion?
Das ist ganz unterschiedlich. Mal sind es nur Systemfunktionen (Das ist dann meist unkritisch, da z.B. eine doppelt ausgeführte Werte-Inkrementierung einfach durch den Bediener korrigiert werden kann), es werden aber meistens Scripte angestoßen. Dies stellt dann ein Problem dar, wenn sich das Script z.B. auf dynamisch ermittelte Bildnummern oder ähnliches abstützt.
Konkret siehe hier:
Code:
Sub OperatorMgmt_showOperatorControl()
' ####################################################################################################
' Steuert den Bediener-Anmeldedialog.
'
' -------------------------------------------------------------------------------------------
' |   Version   | Autor | Änderung                                                           
' -------------------------------------------------------------------------------------------
' | 01_00_00_00 |  fk   | Neuerstellung
'
' ####################################################################################################

    ' ##################################################
    ' Variablenreferenzen holen, Funktion initialisieren
    ' ##################################################


    ' ##############
    ' Funktionslogik
    ' ##############
    
    ' Hilfsvariablen besetzen
    [SIZE=4][B][COLOR=#ff0000]OM_backPageNo = pageCtrl_currentPageNo[/COLOR][/B][/SIZE]
    OMSG_messageNo = 0
    OM_loginPassword = ""
    OM_loginKeySerialNo = currentOperator_keySerialNo
    OM_logBtnsEnabled = (OM_loginKeySerialNo = "")
        
    ' Dialog anzeigen
    ActivateScreen "p0020_OperatorLogControl", 0
End Sub
Wobei ich OM_backPageNo dann für das "Schließen des Dialogs" (Bildwechsel) verwende. Bei Mehrfachtrigger der script-auslösenden Schaltfläche ist das Bild mit dem Anmeldedialog bereits sichtbar, und der zweite Scriptdurchlauf ergibt dann eine falsche Bildnummer.

Klar könnte ich diese spezielle Situation auch anders umschiffen, dennoch ist mir eine allgemein anwendbaren Entprell-Lösung lieber.



Mir würde jetzt nur noch einfallen, mit den Tastendruck ein Script aufzurufen und das da abzufangen.
Richtiges Entprellen geht ja nur über eine Zeit, dann wirst du im Script eine Zeitschleife einbauen.
...
Schon erfolglos probiert, die Mega-Performance der Panels reicht nicht, um eine Schaltfläche mithilfe einer globalen internen Variable rechtzeitig auszublenden.


...
Wenn die Variablen zur Steuerungsanbindung und nicht intern genutzt werden, ist es ganz sauber
die Tasten in der Steuerung zu entprellen.
...
Würde ich ungern tun, da ich 1. Steuerung und HMI grundsätzlich trenne (2 Projekte) und 2. eine auch ohne Steuerungsverbindung lauffähige Bedienoberfläche haben möchte.


...
Zeitschleife, du hast mal in irgendeinen Thread geschrieben, das man Zeiten im Script in 'ms' auflösen
kann. Das konnte ich nachvollziehen, kleinste Basis ist meinens erachtens die Sekunde.
Könntes du noch mal darauf eingehen?
Hier der verwendete Code:
Code:
Sub PauseXms(ByVal timeInMs)
' ####################################################################################################
' Erzeugt eine Pause mit der gegebenen Dauer.
' WICHTIG: Für die Dauer der gegebenen Pausenzeit kann kein anderes Skript ausgeführt werden und die
' CPU-Auslastung des Panels steigt auf 100%, dies beeinträchtigt die gesamte Bedienoberfläche!
'
' -------------------------------------------------------------------------------------------
' |   Version   | Autor | Änderung                                                           
' -------------------------------------------------------------------------------------------
' | 01_00_00_00 |  fk   | Neuerstellung
'
' ####################################################################################################

    ' ##################################################
    ' Variablenreferenzen holen, Funktion initialisieren
    ' ##################################################
    Dim timestamp, pauseTimestamp


    ' ##############
    ' Funktionslogik
    ' ##############
    
    ' Zeitstempel mit Pause berechnen
    timestamp = Timer
    pauseTimestamp = timestamp + (timeInMs / 1000)
        
    ' Endlosschleife
    Do
    Loop Until Timer >= pauseTimestamp
End Sub


Gruß, Fred
 
Das ist ganz unterschiedlich.
Mal sind es nur Systemfunktionen (Das ist dann meist unkritisch, da z.B. eine doppelt ausgeführte Werte-Inkrementierung einfach durch den Bediener korrigiert werden kann), es werden aber meistens Scripte angestoßen.
Tatsächlich? Sogar Funktionen die auf die SPS-Variablen zugreifen kannst du auch doppelt triggern) Das ist ja ganz toll...
Bei den Skripten hätte mich das weniger gewundert dass man es schafft ein und dass selbe gleich 2x hintereinander in die VBS-Queue zu schicken.
Das Problem gab's unter Flex schon.

Dies stellt dann ein Problem dar, wenn sich das Script z.B. auf dynamisch ermittelte Bildnummern oder ähnliches abstützt.
Wenn du dich auf ein Bild stützt würde ich (sofern möglich) beim Aufruf prüfen ob das richtige geöffnet ist.

Löst aber nicht das Grundsatzproblem... Hmm....
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Code:
Sub PauseXms(ByVal timeInMs)
[...]
    ' Zeitstempel mit Pause berechnen
    timestamp = Timer
    [COLOR="#FF0000"]pauseTimestamp[/COLOR] = timestamp + (timeInMs / 1000) [COLOR="#FF0000"]'muß auf Mitternachts-Überschreitung (>= 86400) geprüft werden![/COLOR]
        
    [COLOR="#FF0000"]' Endlosschleife[/COLOR]
    Do
    Loop Until Timer >= pauseTimestamp
End Sub
Die Verwendung der Timer-Funktion ist nicht so trivial wie es auf den ersten Blick aussieht - besonders wenn man sie kurz vor Mitternacht aufruft oder wenn die Panel-Uhr synchronisiert wird. Sonst kann aus der als "Endlosschleife" titulierten Warteschleife tatsächlich eine Endlosschleife werden.
Besser: Now-Funktion verwenden oder bei Mitternachts-Überschreitung in 2 Schleifen zerlegen.

Harald
 
Die Verwendung der Timer-Funktion ist nicht so trivial wie es auf den ersten Blick aussieht - besonders wenn man sie kurz vor Mitternacht aufruft oder wenn die Panel-Uhr synchronisiert wird. Sonst kann aus der als "Endlosschleife" titulierten Warteschleife tatsächlich eine Endlosschleife werden.
Besser: Now-Funktion verwenden oder bei Mitternachts-Überschreitung in 2 Schleifen zerlegen.


Hallo Harald,

löst "Now" denn auch bis Millisekunden auf?
"Timer" soll dies tun:
Code:
The Timer Function returns the number of seconds and milliseconds since 12:00 AM.

[B]Example
[/B]
<%
response.write("Number of seconds and milliseconds since 12:00 AM: ")
response.write(Timer)
%>

 The output of the code above will be:
  Number of seconds and milliseconds since 12:00 AM: 13316.89


Gruß, Fred
 
Tatsächlich? Sogar Funktionen die auf die SPS-Variablen zugreifen kannst du auch doppelt triggern) Das ist ja ganz toll...
...

Hallo RONIN,

laut Siemens werden jegliche Ereignis-Funktionen quasi-parallel gestartet und auch nicht auf deren Ende gewartet. Wenn du also in der ersten Funktion eine Variable inkrementierst, dann kann es strenggenommen passieren, dass eine zweite -diese Variable verwendende- Funktion mit dem alten Wert arbeitet.
Dies ist mir allerdings bis jetzt noch nicht passiert (Oder ich habe es nur nicht bemerkt...:???:)


Gruß, Fred
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Harald,

löst "Now" denn auch bis Millisekunden auf?
"Timer" soll dies tun:
Code:
The Timer Function returns the number of seconds and milliseconds since 12:00 AM.

[B]Example
[/B]
<%
response.write("Number of seconds and milliseconds since 12:00 AM: ")
response.write(Timer)
%>

 The output of the code above will be:
  Number of seconds and milliseconds since 12:00 AM: 13316.89


Gruß, Fred

Ähm Fred,
das hat mir jetzt keine Ruhe gelassen und ich habe mal dein Script erweitert und auf 12'-Comfort laufen lassen.

Code:
Dim timestamp, pauseTimestamp


     
    ' Zeitstempel mit Pause berechnen
    timestamp = Timer
    pauseTimestamp = timestamp + ([COLOR="#FF0000"]10000 [/COLOR]/ 1000)
        
    ' Endlosschleife
    Do
		[COLOR="#FF0000"]SmartTags("HMI_Variable_9") = Timer[/COLOR]
    Loop Until Timer >= pauseTimestamp

Die HMI Variable habe ich mir dann auf den Bildschirm gelegt, diese zählt dann im Sekundentakt
hoch, da ist nichts mit Millisekunden. Dann kannst du bei der sicheren Variante mit 'Now' bleiben.

Deine Information mit den Millisekunden ist das vielleicht VB und nicht VBS?

Wobei bei Microsoft auf der Seite wird auch nur von Sekunden gesprochen.
 
Zuletzt bearbeitet:
Hmm, in der Simulation WinCC flexible 2008 SP2 liefert Timer() tatsächlich die Zeit seit Mitternacht mit einer Granularität von anscheinend 10ms.
Will man das wirklich nutzen, dann muß man das VBS aber zwingen, die Auswertung als Gleitpunkt zu machen oder den Timer()-Wert vor der Auswertung mit 1000 multiplizieren und dadurch in ms zu operieren.

So könnte es tatsächlich mit ms-Auflösung funktionieren (nicht getestet):
Code:
    ' Pause-Endzeitpunkt berechnen
    pauseTimestamp = Timer * 1000.0 + timeInMs

    ' Warteschleife
    Do
        jetzt = Timer * 1000.0
    Loop Until jetzt >= pauseTimestamp
(wobei auch hier noch der Mitternachts-Überlauf abgefangen werden muß)

Harald
 
jetzt habe ich es auch, wenn man mit 1000 erweitert, lösst er in ms auf.

Aber warum ist das so? Warum schreibt er den wert von 'Time' nicht direkt ohne
erweiterung in eine DINT Variabel.


EDIT: jetzt habe ich es man muss logischerweise das Format für die Variabel in REAL angeben, dann geht es.

@Fred
@Harald
erst einmal Danke, auch wenn es Optopic war, das habe ich gebraucht.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Und mit einem Hilfsbit geht das nicht?Also das man das Script nur einmal durchläuft und dann Visu Bit und Hilfsbit abfrägt?
In das Script rein gehe ich nur wenn das Hilfsbit nicht sitzt.Dort setze ich es.Am Ende von Code setzt man beide Bits zurück.
 
Und mit einem Hilfsbit geht das nicht?Also das man das Script nur einmal durchläuft und dann Visu Bit und Hilfsbit abfrägt?
In das Script rein gehe ich nur wenn das Hilfsbit nicht sitzt.Dort setze ich es.Am Ende von Code setzt man beide Bits zurück.
Problem ist hier dass ein Skript schon während es läuft noch einmal getriggert werden kann oder gar schon 2x mal bevor es das erste mal abgearbeitet wird.

2x Skripttrigger - 2x Skript in Warteschlange - Erster Skriptaufruf - Rücksetzen deines Hilfbits am Ende - Zweiter Skriptaufruf (aus der Warteschlage).
Das ist eigentlich das Hauptproblem. Innerhalb des Skripts kann man das schwer bis kaum abfangen.
 
Und durch was wird es getriggert?Kann das nicht vom Anwender verhindert werden?Wenn ich in der Visu das Tastenbit setze.Kann ich doch nicht nachtriggern.
Das verstehe ich jetzt nicht.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Und durch was wird es getriggert?Kann das nicht vom Anwender verhindert werden?Wenn ich in der Visu das Tastenbit setze.Kann ich doch nicht nachtriggern.
Das verstehe ich jetzt nicht.

Das ist ja meine Grundidee: Verwendung einer direkt durch die Schaltfläche gesetzten Hilfsvariable, um eine Doppelbedienung durch den Bediener zu verhindern (siehe mein erstes Posting).
Unschön daran ist, dass ich dies dann strenggenommen bei jeder Schaltfläche tun müsste und dieser Projektierungsschritt quasi unsichtbar (nicht in einem durch eine Versionsverwaltung dokumentierbaren Script) ist.


Gruß, Fred
 
Zurück
Oben