Hallo liebe Leute, ich hätte mal eine Frage zum Entprellen… Was will ich machen: Ich möchte menschliche Reaktionszeiten mit Hilfe einer LED und eines Tasters auf die Millisekunde genau messen können. Des Weiteren möchte ich den Zeitpunkt eines Tastendrucks sowie den Zeitpunkt des Tastenloslassens erfassen. Wie will ich es machen: Ich nutze ein Arduino Board mit einem ATmega328P-PU (16Mhz Quarz) und bestücke es mit einer LED und drei Tastern. Programmieren tue ich in C++ mit dem Atmel Studio 6. Sobald die LED leuchtet, soll man so schnell wie möglich mit einem Tastendruck reagieren. Die Zeit zwischen dem Einschalten der LED und dem Drücken des Tasters möchte ich als Reaktionszeit Speichern und an meinen PC schicken. Die Zeit messe ich hierbei mit einem Timer der folgendermaßen konfiguriert ist: (Takt 16MHz) Timer: TIMER0 (8-Bit) Prescaler: 64 //16000000/64=250000 Modus: CTC Compare Value: 249 //250000/250=1000 Wenn ich nichts falsch gemacht habe, sollte die ISR mit dieser Konfiguration jede Millisekunde angesprungen werden. Die ISR ist im Anhang untergebracht. Zum Entprellen des Tasters nutze ich eine abgeänderte Entprellroutine von Peter Dannegger (hoffe ich habe sie nicht verunstaltet), da ich gerne drei Taster gleichzeitig verwenden möchte. Wenn ich jetzt den Taster drücke, wird der 3-Bit Counter jede Millisekunde heruntergezählt. Bei mir wären das dann 8 Millisekunden DEBOUNCE_TIME (wenn ich nicht irre). Ein kleines Beispiel: 1. LED zum Zeitpunkt t1 = 1000ms aktivieren 2. Tastendruck wird zum Zeitpunkt t2 = 1308ms erkannt 3. t2 – DEBOUNCE_TIME – t1 = Reaktionszeit = 300ms Mein Problem: Ich habe heute festgestellt, dass die Debounce_Time nicht immer genau 8 Millisekunden beträgt?! Das hab ich leicht übersehen.... Denn wenn der Taster prellt und sich kurzzeitig wieder im letzten bekannten entprellten Zustand befindet während die ISR angesprungen wird, dann wird der Counter wieder zurückgesetzt und beginnt wieder bei 7 mit dem Runterzählen. Wenn das tatsächlich häufiger sein sollte und ich nicht irgendeinen Schmarrn denke, wie kann ich dieses Problem umgehen?? Ich möchte maximal eine Millisekunde bei der Erfassung der Reaktionszeit danebenliegen. Bin wie immer für jede Hilfe dankbar. Solltet ihr sonst irgendwelche Fehler im Programm finden dann zögert nicht es mir mitzuteilen, ich bin schon gespannt was diesmal alles falsch ist :/ Viele Grüße, Steve-o
Wen du die Reaktionszeit messen willst, solltest du tunlichst nicht entprellen. Denn sonst misst du die Reaktionszeit + Tasterprellen + Entprellzeit. Und zumindest die dir letzten beiden kann der Proband nichts... :-o
@Lothar: Ich verstehe was du meinst aber wenn ich nicht entprelle, dann kommt auch nicht nur eine Reaktionszeit an sondern 2 oder 3 und das Programm wird unberechenbar. Hat jemand ne konkrete Idee wie ich das mit Entprellen hinbekommen könnte? Thx
nachdem die led sich geändert hat misst du einfach die Zeit bis sich irgendwas tut am Taster dann wird der aktuelle wert der Zeit gespeichert /übermittelt entprellen brauchst du nicht. nächsten Wert kann es erst geben wenn die led geändert wurde und NICHT wenn sich der Taster ändert
@Jonas: Ja das ist eine gute Idee, nur leider habe ich in der Beschreibung etwas vergessen. Ich möchte alle Tastendrücke aufzeichnen, egal welchen Zustand die LED hat. Nur wenn die LED an ist und ein Tastendruck erfolgt wird zusätzlich noch die Reaktionszeit übertragen. Ansonsten nur die Zeitpunkte der Tastendrücke bzw. des Loslassens. Sry für die ungenaue Angabe, Grüße, Steve-o
Was für Ideen brauchst Du noch???? Vorschlag: Überleg Dir einfach wie Du einen tastendruck erkennen würdest, wenn Du das Programm wärst. Hilfestelung: 1. Beobachte den Input-Pin 2. Er ist high oder low was immer gedrückt heißt, aktuelle Zeit speichern 3. In den nächsten x milliSekunden ignorierst Du den Input-Pin, da die Taste ja prellen kann 4. Jetzt beobachstest Du wieder den Input-Pin 5. Wenn die Taste losgelassen wird, so speichere die aktuelle Zeit 6. Wiederhole Punkt 3, die Taste kann ja prellen. 7. Fang bei Punkt 1 wieder an Was Du mit dieser Prozedur machst ist a) Erkennen des Wechsels am Input-Pin (press - release) b) Du erfaßt alle Dir wichtigen Zeiten ohne Verzögerung. Was Du beachten solltest: Störimpulse aus der Umgebung sollten keinen Tastendruck vortäuschen -> niederohmig aufbauen = laß ruhig ein paar Milliampere durch die Taste fließen Verwende eine robuste Taste, die Testpersonen werden kräftig draufhauen Für die Zukunft: Selber denken ;-)
Nachdem eine Taste gedrückt wurde darfst Du halt eine gewisse Zeit lang alle weiteren Pin-Wackler nicht berücksichtigen. Sagen wir mal, Du hast einen Timer-Interrupt, der jede Millisekunde kommt. Dann könnte es in etwa so aussehen:
1 | #define TASTER_ANZAHL 3
|
2 | #define ENTPRELL_ZEIT 8
|
3 | |
4 | uint8_t entprell_zaehler[TASTER_ANZAHL] = {0}; |
5 | |
6 | TIMER_ISR() |
7 | {
|
8 | for (uint8_t i = 0; i < TASTER_ANZAHL; i++) { |
9 | if (entprell_zaehler[i] > 0) { |
10 | // Entprellzeit läuft noch => Änderungen ignorieren
|
11 | entprell_zaehler[i]--; |
12 | } else { |
13 | // Entprellzeit abgelaufen => Änderungen auswerten
|
14 | if (taste_geaendert(i)) { |
15 | aktion_aufzeichnen(i); |
16 | entprell_zahler[i] = ENTPRELL_ZEIT; |
17 | }
|
18 | }
|
19 | }
|
20 | }
|
Im Grunde läuft es darauf hinaus, dass du jede Änderung des Tastenzustands erst mal als vom Benutzer verursacht ansiehst. Mit einer Ausnahme: Wenn die Zeit zwischen den Wechseln zu kurz war, dann KANN das nicht benutzerverursacht sein. Kein Mensch, egal wie schnell er ist, schafft es eine Taste innerhalb von 5 Millisekunden zu drücken und wieder loszulassen. Als die ersten Digitaluhren mit Stoppfunktion aufkamen, war es unter uns Schülern ein beliebtes Spiel die Start/Stop Taste so schnell es geht 2 mal hintereinander zu drücken. Schneller als ein paar Hunderstel-Sekunden ging nicht. Meist war man im Bereich von so um die 14 Hunderstel. D.h. da bist du mit deinen Millisekunden noch relativ weit weg. Eine Reaktionszeit von signifikant weniger als einer Zehntel Sekunde nach dem Aufleuchten einer LED würde ich ehrlich gesagt in das Reich der Fabel verweisen. Das ist entweder pures Glück, sprich er hat mit dem Drücken schon begonnen als die LED noch gar nicht geleuchtet hat oder ein Messfehler. Und schon rein aus mechanischen Gründen kann ein Tastendruck auch nicht beliebig kurz sein.
Hey Jungs! Vielen Dank an alle für die Hilfe. @spontan: diese Lösung hatte ich früher bereits aber ich habe gehofft, dass es vielleicht noch schöner geht. Gedacht habe ich selber ;) Werd jetzt wieder auf die alte Version zurückgreifen. Thx again, Stefan
Was hat Dir an Deiner Lösung nicht gefallen? Sie ist simple und funktioniert. Das mit dem Denken: Hier im Forum weiß man nie wer wirklich denkt und wer zu faul ist. Gut für Dich, daß Du mitdenkst. Denken ist allen Menschen erlaubt, vielen bleibts erspart.
@spontan: Ich hatte damals das Problem, dass ich, wie Karl Heinz schon erwähnt hat, an guten Tagen für einen Tastendruck unter 20ms gebraucht habe. Wenn ich bei dieser Lösung eine fixe Zeit festlege, die ich den Taster nach einem Statuswechsel ignoriere, z.B. 20ms, dann geht das Tastenloslassen evtl. verloren. Weil der Taster bis dahin noch ignoriert wird... wenn ich die Zeit allerdings zu kruz wähle z.B. 5ms, dann könnte es passieren, dass der Taster noch prellt und das wieder Probleme macht. Ist aber letztlich nicht sooo häufig passiert. Aber wenn die Leute darauf rumhauen kann es schon mal vorkommen... Das war auf jeden Fall der Grund, warum ich nach einer "schöneren" Lösung gesucht habe. Ein weiterer Punkt: ich weiß auf Grund von Informationsmangel noch nicht welche Taster am Schluss verwendet werden sollen.. vielleicht sind sie alt und prellen viel, vielleicht sind sie auch hochwertig und schön robust... :/
Steve schrabte:
>...an guten Tagen für einen Tastendruck unter 20ms gebraucht habe.
Ach Du bist das, der den Takt für die Netzspannung erzeugt!
;-)
MfG Paul
Das lag nicht an mir weil ich schneller bin als die Polizei erlaubt sonder irgendwie am Taster... keinen Plan was da passiert ist aber wenn ich mit dem Finger so schnell es ging drüber gewischt habe ist das ab und zu so passiert. Vielleicht lags auch an meinem Programm und ich habe die Zeit falsch erfasst, was leider durchaus auch möglich ist :) Dann möchte ich kurz fragen: Wie lange dauert ein Tastendruck mit Loslassen denn in der Regel.. also bei sehr schnellen Menschen?
>wenn ich die Zeit allerdings zu kruz wähle z.B. 5ms, dann könnte >es passieren, dass der Taster noch prellt und das wieder Probleme macht. Hatte noch nie einen Taster, der länger als 8 msec prellt. Wenn Du welche hast, dann schmeiß sie weg. Mit übernommenen Entprellroutinen wirst Du immer Probleme haben, die geben den Status "Taste betätigt" erst zurück, wenn die "Prellzeit" vorbei ist. Das aber willst Du nicht, Du willst erkennen, wenn der Schalter sich bewegt, von low nach high oder anders rum. Somit mußt Du zwangsweise die obige Methode anwenden. Nimm zehn msec als Totzeit und erkenne erst dann ein neuerliches Bewegen des Schalters an. Mach eine Versuchsreihe mit den gemessenen Betätigungszeiten, sollten da welche mit obigen 10msec drin sein, so ist das verdächtig, d.h. der User kann eine Taste in 10 msec betätigen und auch wieder loslassen. Ich mag mit Dir wetten, daß der Fall nicht auftritt. Im Klartext, eine Betätigung für nur 10 msec wird nicht vorkommen.
Steve-o Bane schrieb: > Ich möchte menschliche Reaktionszeiten mit Hilfe einer LED und eines > Tasters auf die Millisekunde genau messen können. Steve-o Bane schrieb: > Wenn ich nichts falsch gemacht habe, sollte die ISR mit dieser > Konfiguration jede Millisekunde angesprungen werden. Mit einer Abtastrate von einer Millisekunde kannst du keine Messung mit einer Auflösung von einer Millisekunde machen. Bei DSOs wird hier immer eine 10fach höhere Abtastrate als die Signalfrequenz empfohlen. Und mit einem Sensor, der selbst undefiniertes Verhalten (prellen) im Bereich mehrerer Millisekunden liefert, wird das nicht besser. MfG Klaus
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.