Prüfen, ob Taster x mal gedrückt wurde?

Hallo Leute,

brauche mal wieder eure Hilfe:

Möchte mein Programm über einen einzigen taster steuern:

Taster in bestimmter Zeit 1 mal gedrückt --> tue das Taster in bestimmter Zeit 2 mal gedrückt --> tue dies Taster in bestimmter Zeit 3 mal gedrückt --> tue noch was anderes usw.

durch einmaliges Drücken soll dann das Programm beendet und erst dann ein (über ein Poti eingestellter Wert) in die Hauptsteuerung übernommen werden.

habt ihr da irgendwelche Anregungen für mich, wie das zu realisieren wäre?

Wie immer schonmal vielen Dank für eure Hilfe im Voraus.

Freundliche Grüße

gugg mal hier:

http://arduino.cc/en/Tutorial/ButtonStateChange

in dem beispiel kannst du nachlesen, wie man einen taster abfragt. mir hat das beispiel sehr geholfen! (ich hab gerade sowas ähnliches programmiert - mit einem taster kann eine lampe eingeschaltet werden und dann bei jedem tastendruck wird sie über pwm gedimmt. falls du also noch fragen hast, kann ich dir denke ich helfen.)

viel erfolg!

Und die Zeit bestimmst Du mittels millis() siehe arduino.cc/en/Tutorial/BlinkWithoutDelay

Die Logik x Tastendrücke in y Zeit hat einen Nachteil. Da mußt Du nämlich immer y Zeit warten bis Du etwas machen kannst. Besser ist die Zeit zwischen Loslassen und Wieder-Drücken zu erfassen und falls diese über einer gewissen Zeit ist ist die Eingabe als abgeschlossen anzusehen und die Auswertung der Anzahl der Tastendrücke kann erfolgen.

grüße Uwe

gugg ma auch hier:

https://code.google.com/p/clickbutton/

guggst du:

http://www.mathertel.de/Arduino/OneButtonLibrary.aspx

ClickButton gefällt mir besser aber es kommt auf den einsatzzweck an

comp_controller:
habt ihr da irgendwelche Anregungen für mich, wie das zu realisieren wäre?

Geht ja kaum anders als mit Entprellen der Tastendrücke und Timeout nach dem letzten Tastendruck.

Mit einer Timeout-Zeit von 600 ms (im Programm einstellbar per #define) mal ein Demo-Sketch mit einer Zählfunktion gemacht:

#define BUTTONPIN 2
#define INPUT_TYPE INPUT_PULLUP
#define BOUNCETIME 5
#define TIMEOUT 600

void setup() {
  Serial.begin(9600);
  Serial.println("Buttoncount by 'jurs' for German Arduino Forum");
  pinMode(BUTTONPIN,INPUT_TYPE);
}

byte pressCount()
{
  static byte count=0;
  static unsigned long lastRunMillis=0;
  static boolean lastDown=false;
  static unsigned long lastDownMillis=0;
  unsigned long thisMillis=millis();
  if (thisMillis-lastRunMillis<BOUNCETIME) return 0;
  lastRunMillis=thisMillis;
  boolean nowDown= digitalRead(BUTTONPIN);
  if (INPUT_TYPE==INPUT_PULLUP) nowDown=!nowDown;
  if (nowDown==true && lastDown==false) 
  {
    count++;
    lastDown=nowDown;
    lastDownMillis=thisMillis;
  }
  lastDown=nowDown;
  if (thisMillis-lastDownMillis>TIMEOUT)
  {
    byte temp=count;
    count=0;
    return temp;
  }
  else return 0;
}


void loop() {
  byte number=pressCount();
  if (number!=0) Serial.println(number);
}

Wenn der Button mit PullDown-Widerstand angeschlossen wird, INPUT_TYPE als INPUT definieren.
Wenn am Button der interne PullUp-Widerstand aktiviert werden soll, INPUT_TYPE als INPUT_PULLUP definieren.

Einknopf-Bedienungen nutzen auch gern kurze / lange Tastendrücke,
Und brauchen ein feedback wo man ist.
Bei kurzem Druck wird ( beim Loslassen ) weitergezählt und angezeigt,
Bei langem Druck wird ( wenn die Dauer für “lang” erreicht ist) , die vorher angewählte Aktion ausgeführt und angezeigt.

  • Prellen zählt natürlich nicht als kurz :wink:

michael_x: Einknopf-Bedienungen nutzen auch gern kurze / lange Tastendrücke,

Wo hier fast alle drauf aus sind lange und kurze Tastendrücke zu unterscheiden, fällt mir noch ein:

Das ließe sich in meinen Code zum Zählen von Tastendrücken natürlich auch noch zusätzlich einbauen. Man könnte dann nicht nur x Tastendrücke zählen, sondern auch feststellen, ob diese mit einem letzten kurzen oder letzten langen Tastendruck beendet wurden.

Funktion 3K wie kurz wäre dann: drücken-loslassen-drücken-loslassen-drücken-loslassen

Funktion 3L wie lang wäre dann: drücken-loslassen-drücken-loslassen-drücken und halten

So könnte man zu jeder Anzahl gedrückter Tasten nicht nur eine, sondern sogar zwei Funktionen realisieren.

Die Funktion müßte dazu nur zu dem Zeitpunkt, wenn der Timeout auftritt und die Anzahl zurückgeliefert wird, einmal kurz per digitalRead feststellen, ob die Taste gedrückt ist oder nicht, und das Ergebnis in geeigneter Form zusätzlich zur Anzahl der Tastendrücke zurückliefern. Die Änderung könnte ich in meinen Code auch noch leicht einbauen, falls gewünscht. Und dann hätte man schon mit 1 bis 5 Tastendrücken tatsächlich 10 verschiedene Schaltmöglichkeiten.

Das wäre vermutlich insbesondere dann interessant, wenn es um das Ein- und Ausschalten von Geräten geht. So könnte die Zahl für das Gerät stehen, kurz oder lang für ein oder aus. Z.B.: 3K ==> Gerät 3 ein 3L ==> Gerät 3 aus 4K==> Gerät 4 ein 4L==> Gerät 4 aus etc.

Muss man ausprobieren, ob das bedienbar ist. Du hast dann eben nicht nur kurze/lange Tastendrücke, sondern auch kurze/lange Pausen. (woran erkennst du, dass 3K gemeint war und nicht eine 4x Funktion kommen wird) ? Wie kann man eine versehentlich gestartete oder zu weit gezählte Sequenz abbrechen ???

Dann können wir gleich einen Morsecoder Interpreter schreiben ;) ;) ;) ;) Grüße Uwe

michael_x:
Muss man ausprobieren, ob das bedienbar ist.
Du hast dann eben nicht nur kurze/lange Tastendrücke, sondern auch kurze/lange Pausen.

Im Moment arbeitet der Code nur mit kurzen Tastendrücken, die innerhalb von maximal 0,6s aufeinanderfolgen müssen. Die Auswertung erfolgt immer per Timeout 0,6s nach dem letzten Tastendruck. Bis dahin liefert die Funktion immer 0 zurück und zählt nur intern. Nach dem Timeout wird der Stand des Druckzählers zu diesem Zeitpunkt zurückgeliefert und dieser auf 0 zurückgesetzt.

Jeder Befehl wird also immer 0,6s nach dem letzten Tastendruck ausgeführt.

Und an dem schnellen Drücken beim Hochzählen ändert sich bei der Bedienung auch nichts, wenn man am Ende lang/kurz unterscheiden möchte. Der Unterschied ist nur:

Für x-mal Tastendruck und am Ende kurz: x-mal den Taster drücken und am Ende sofort loslassen
Für x-mal Tastendruck und am Ende lang: x-mal den Taster drücken und am Ende noch eine Sekunde gedrückt halten, danach loslassen

Allerdings müßte der Code dafür noch geringfügig geändert werden und man müßte sich überlegen, wie man die lang/kurz Information zurückliefert, ob in einem extra Call-by-Reference Parameter der Funktion oder z.B. im höherwertigsten Bit des Rückgabewerts.

michael_x:
(woran erkennst du, dass 3K gemeint war und nicht eine 4x Funktion kommen wird) ?

Wenn zwei Tastendrücke nicht in maximal 0,6s aufeinander folgen, wird der nächste Tastendruck als Beginn einer neuen Druckfolge erkannt.

michael_x:
Wie kann man eine versehentlich gestartete oder zu weit gezählte Sequenz abbrechen ???

Im Prinzip gibt es eine “längste Druckfolge”, die in einen Befehl umgesetzt wird. Sagen wir mal von 1 bis 10 Tastendrücke behandelt das Programm. Dann muß das Programm wenn 11, 12, 13 oder noch mehr Tastendrücke geliefert werden, einfach keinen Befehl ausführen. Und das ist auch die Blaupause für den Abbruch: Wenn einem beim dritten mal Drücken einfällt, dass man jetzt eigentlich doch keinen Befehl starten möchte, einfach nochmal zusätzlich die Maximalzahl drücken (10mal), dann ist der Befehl auf jeden Fall abgebrochen.

Die Steigerung wäre dann, wie von Uwe erwähnt, der Morsecode-Interpreter. Dann kann man mit einem Taster die Buchstaben A-Z, die Ziffern und einige Satzzeichen eingeben. Aber dann ist die Bedienung wohl dem Bediener wirklich schwerer beizubringen als dem Arduino. Heutezutage können nicht viele Menschen Morsecode eintasten.

Heutezutage können nicht viele Menschen Morsecode eintasten

;) Selbst wenn jeder Tastendruck einen Display-Feedback hat, empfinden viele Menschen es als äusserst mühsam, durch mehrfaches Drücken irgendwohin zu "navigieren". Dass man bei deinem Vorschlag nur 0.6 sec hat zu überlegen, ob man nochmal drücken soll oder nicht, spricht für einen Morselehrgang als Benutzertraining.

michael_x: Selbst wenn jeder Tastendruck einen Display-Feedback hat, empfinden viele Menschen es als äusserst mühsam, durch mehrfaches Drücken irgendwohin zu "navigieren". Dass man bei deinem Vorschlag nur 0.6 sec hat zu überlegen, ob man nochmal drücken soll oder nicht, spricht für einen Morselehrgang als Benutzertraining.

Irgendwie hast Du etwas aus den Augen verloren, wofür das sein soll. Das soll NICHT für eine interaktive Menüsteuerung mit Display und optischem Feedback des gewählten Menüpunkts sein, sondern das soll dafür sein, wie es angefragt wurde:

Möchte mein Programm über einen einzigen taster steuern:

Taster in bestimmter Zeit 1 mal gedrückt --> tue das
Taster in bestimmter Zeit 2 mal gedrückt --> tue dies
Taster in bestimmter Zeit 3 mal gedrückt --> tue noch was anderes
usw.

Also z.B.:

Taster 1 mal gedrückt --> Motor aus
Taster 2 mal gedrückt --> Motor Linkslauf ein
Taster 3 mal gedrückt --> Motor Rechtslauf ein
Taster 4 mal gedrückt --> Licht an
Taster 5 mal gedrückt --> Licht aus

Die Funktionen stehen im Bedienerhandbuch, in dem man vorher nachschlägt. Oder es steht fest aufgedruckt auf einer kleinen Plakette am Gehäuse. Oder man hat es im Kopf.

Und dann weiß man vorher, wie oft man drücken muß um welche Aktion zu starten, und sobald man den Finger auf den Button legt, muß man beim Drücken nur noch mitzählen. Ohne überlegen zu müssen, wie oft.

Oder man hat es im Kopf

Sag ich doch:

spricht für einen Morselehrgang als Benutzertraining.

:P