Tastatur entprellen / Keyboard anti bouncing

  • Guten Tag,

    Ich habe eine mechanische Tastatur (MX-Brown Switches von Cherry), die immer wieder mehrfache Tastenanschläge erzeugt (bei bestimmten Tasten), obwohl die Taste nur einmal gedrückt wurde. Damit bin ich nicht der Einzige, solche Probleme sind häufiger anzutreffen (insbesondere bei mechanischen Tastaturen).

    Um dieses Problem zu lösen und ohne eine neue Tastatur erwerben zu müssen, habe ich eine Software programmiert, die eine softwareseitige "entprellung" ermöglicht.


    Hier der Sourcecode, ist eine Menge WinApi Kram, steigt wahrschenlich niemand durch :D (kommentiert habe ich da eher nicht)

    (Verbesserungen wurden in den Code eingebaut 03-08-2016 - 02:39)


    Dazu benötigt man eine "Settings.ini"

    Code
    [Delay]
    Time_ms=6
    [Used_Chars]
    Chars=uioln
    [Autostart]
    Enable=yes


    Erklärung der Settings:
    [Time] - Time_ms = Entprell Zeit in Millisekunden
    [Used_Chars] - Chars = Buchstaben die entprellt werden sollen
    [Autostart] - Enable = yes für Autostart, irgendetwas anderes für keinen Autostart


    Viel Spaß damit, falls ihr damit etwas anfangen könnt

    MfG

    2 Mal editiert, zuletzt von KloMeister (3. August 2016 um 02:38)

  • Hi,

    Warum der Umweg über einen Hook, zum Blocken von doppelten Eingaben sollte ein Hotkey völlig ausreichend sein, oder?

    Folgende Variablen sind übrigens alle Global, dass Local davorsteht ist ändert daran nichts:

    AutoIt
    Global $g_hHook, $g_hStub_KeyProc, $g_sBuffer = ""
    Local $DelayTime = IniRead(@WorkingDir & "\Settings.ini", "Delay", "Time_ms", "5")
    Local $Keys = IniRead(@WorkingDir & "\Settings.ini", "Used_Chars", "Chars", "")
    Local $Auto = IniRead(@WorkingDir & "\Settings.ini", "Autostart", "Enable", "")
    local $BlockedHotkey
    local $pause = 0

    Lokale Variablen können nur innerhalb von Funktionen erstellt werden.

    mfg

    Zeitriss

  • Die Tasten werden über HotKeySet geblockt, die Abfrage über HotKey wäre aber zu kritisch, da die Taste ja erstmal geblockt werden würde. Ich müsste sie also dann mit Hilfe von Send durch AutoIt nachträglich senden. Wie viel Delay wäre das wohl? Wer möchte als Gamer Delay auf seinen Tasten haben?

    Deswegen wird die gedrückte Taste über einen Hook abgefragt (was wohl die schnellste Methode ist) und auch noch gesendet, anschließend geblockt für xx Millisekunden.

    2 Mal editiert, zuletzt von KloMeister (2. August 2016 um 22:01)

  • Ich gebe dann auch mal meinen Senf hinzu...

    Zeile 23/25 - sind überflüssig...
    $g_hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($g_hStub_KeyProc), _WinAPI_GetModuleHandle(0))


    Zeile 28/30 - bei nur einem Befehl kann man das in einer Zeile machen...
    If $pause = 0 Then HotKeySet("{" & $BlockedHotkey & "}")


    Zeile 31-34 - das geht auch mit nur einer Zeile...
    If TrayGetMsg() = $idExit Then ExitLoop


    Zeile 35 - die wichtigste Zeile im Script... grins


    Zeile 40 - ist überflüssig... bzw. das abschließende 'a' muss weg, wobei man diese Zuweisung auch wieder mit nur einer Zeile erledigen kann.
    Local $tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)


    Zeile 41 - wäre nach Zeile 44 besser aufgehoben... wobei man Zeile 42-44 auch wieder mit nur einer Zeile erledigen kann.
    If $nCode < 0 Then Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam)


    Zeile 45/46 - warum fragst du nach $WM_KEYDOWN, wenn es dich nicht interessiert?
    If $wParam = $WM_KEYUP Then ; und das Else ist somit überflüssig...


    Zeile 47 - $iFlags wird nirgends verwendet - die Zeile ist ergo überflüssig...


    Zeile 48/50/51 - Hust... bei jedem Durchlauf werden die Werte erneut umgewandelt - sehr unfein!
    Nach dem Einlesen aus der Ini einmalig konvertieren und in ein Array speichern...


    Zeile 59 - Handelt es sich um eine zu blockende Taste, würde ich das erste Event weiterleiten und alle folgenden unterschlagen, bis die Delaytime ( Timer() ) abgelaufen ist.
    Ein HotKeySet() wäre damit überflüssig. Zudem überprüfst du nicht einmal, ob das HotKey gesetzt werden konnte...

  • Vielen Dank für die Analyse des Codes!
    Ja das passiert wenn man sich Beispiele kopiert, die anpasst und dann einige Rückstände im Code bleiben. (Sonderlich sorgfältig war ich allerdings nicht)

    Ich habe das meiste verbessert (Der SourceCode oben im ersten Post wurde angepasst, damit die Besucher gleich den aktuellsten Code sehen ohne alles lesen zu müssen). Bis auf den Array der bei Beginn eingelesen werden sollte, ist soweit alles eingebaut.


    Nun habe ich allerdings eine Frage. Ich habe jetzt nichtmehr mit Hotkeyset geblockt, sondern indem ich "Return 1" zurückgebe. Damit werden allerdings alle Tasten (kurzzeitig) geblockt (Fällt zwar nicht auf, weil eh Niemand so schnell tippt, aber trotzdem eher doof). Welchen Wert muss ich zurückgeben, damit wirklich nur die entsprechende Taste (kurzzeitig) geblockt wird, die auch gedrückt wurde?
    Danke

    5 Mal editiert, zuletzt von KloMeister (3. August 2016 um 03:25)

  • Kann es sein, dass deine Hardware defekt ist? Das Entprellen sollte eigentlich die Hardware übernehmen. Auch wenn es bei vielen Auftritt - Gerade dann würde ich beim Hersteller ein neues Gerät anfordern.

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal

  • Die Garantie ist wahrscheinlich schon abgelaufen und außerdem wird meine Tastatur (Zowie Celeritas) nichtmehr hergestellt, wird also schwer da überhaupt noch Ersatz zu bekommen.

    Kostete leider um die 100€

    Irgendwann wenn mir mal wieder ein Modell einer mechanischen Tastatur zusagt, schlage ich wieder zu... Solange muss ich jetzt wohl noch mit dieser Tastatur auskommen.

    Einmal editiert, zuletzt von KloMeister (3. August 2016 um 13:09)

  • Ich habe mal ein wenig experimentiert... und auch ein paar Infos als Kommentar eingefügt. :D

    Anti_Key_Bouncing()

    Einmal editiert, zuletzt von Bitnugger (3. August 2016 um 15:35)

  • Wie funktioniert das jetzt mit der .ini? Weil bei mir sagt er jetzt nurnoch keine .ini File gefunden. So wie ich das verstanden habe schaut der nach einer .ini Datei im aktuellen Ordner, egal wie sie heißt? Scheint aber wohl nicht zu funktionieren

    Und das du den "Delay" jetzt abhängig von der Verzögerung für die "Wiederholrate" machst, versteh ich auch nicht. Das sind die Eigenschaften wenn ich eine Taste gedrückt halte. Wenn ich eine Taste einzeln wiederholt drücke, dann kann die Verzögerung deutlich geringer sein als diese eingestellte für die gedrückte Taste. Als Gamer wäre das fatal wenn ich 500ms keine Taste mehr drücken könnte.

    Das Prellen ist ja ein mechanischer Prozess der sich wahrscheinlich im µs Beriech, höchstens niedrigen ms Bereich befindet.

    3 Mal editiert, zuletzt von KloMeister (3. August 2016 um 15:51)

  • Das IniFile heißt bis auf die Extension genauso wie das Script - nur eben nicht *.au3|*.exe, sondern *.ini.

    Anti_Key_Bouncing.au3 --> Anti_Key_Bouncing.ini
    Anti_Key_Bouncing.exe --> Anti_Key_Bouncing.ini