Forum: Mikrocontroller und Digitale Elektronik Arduino Taster entprellen


von Martin M. (ats3788)


Lesenswert?

Hallo
Ich spiele ein wenig mit dem leidigen Thema Entprellen von Taster, 
herum.
Da gibt es den genialen Beitrag
https://www.mikrocontroller.net/articles/Entprellung

Meine Frage, gibt es eine, Function für den Arduino 328p wo ich den 
Taster über Interrupt Int0 oder Int1 abfrage ?
 Zum debouching gibt es viel Infos, leider habe ich nicht mit Interrupt 
gefunden.

[Schreibfehler in Ueberschrift korrigiert - Mod]

: Bearbeitet durch Moderator
von MaWin (Gast)


Lesenswert?

Martin M. schrieb:
> Da gibt es den genialen Beitrag
> https://www.mikrocontroller.net/articles/Entprellung

Na also, gut informiert.

> Meine Frage, gibt es eine, Function für den Arduino 328p wo ich den
> Taster über Interrupt Int0 oder Int1 abfrage

Warum liest du nicht einfach den gefundenen Artikel um zu verstehen, 
dass prellende Kontakte niemals an Interrupt-auslösende Eingänge dürfen.

von Guest (Gast)


Lesenswert?

Ich würde ja vorschlagen den Taster extern zu entprellen, wenn er durch 
einen Interrupt ausgewertet werden soll, aber wie ich vor kurzem im 
Beitrag:

Beitrag "GPIO entstören - Serienwiderstand benötigt?"

lernen durfte machen das nur Anfänger :D

Beitrag #6255394 wurde von einem Moderator gelöscht.
von Martin M. (ats3788)


Lesenswert?

Ja danke
Ich habe mir da was bebastelt schalte einfach den externen Interrupt für 
die Zahl X aus. Warum kann man nicht freundlich bleiben, ich habe ein 
Gesundheitliches Problem  und kann leider kaum noch längere komplexe 
Inhalte lesen. µC geben mir Erfüllung und Spaß.
Einen schönen Tag noch und bleibt gesund

#include <Arduino.h>

#define TOGGLE(x) digitalWrite(x, digitalRead(x) ? LOW : HIGH)
#define TasterPin 2

bool bGlobalTasterState = false;
bool bToggleTaster = false;

void InitTaster();
void Debounce4Int0();
void setup() {
  Serial.begin(34800);
  pinMode(LED_BUILTIN, OUTPUT);

  InitTaster();
}
void loop() {

delay(100);
}




void InitTaster()
{
   pinMode(TasterPin, INPUT_PULLUP);
   attachInterrupt(digitalPinToInterrupt(TasterPin) ,  Debounce4Int0 , 
LOW);
   EIMSK = B00000001; // Interrupt on
}


void Debounce4Int0()
{
EIMSK = B00000000; // Interrupt off


  bToggleTaster = !bToggleTaster;
  TOGGLE(LED_BUILTIN);
  Serial.print("---> ");
  Serial.print(bGlobalTasterState);
  Serial.print(" <---> ");
  Serial.print(bToggleTaster);
  Serial.println(" <---");
  bGlobalTasterState = bToggleTaster;
_delay_ms(350); // Time for delay
EIMSK = B00000001; // Interrupt off
}

von Stefan F. (Gast)


Lesenswert?

Martin M. schrieb:
> Zum debouching gibt es viel Infos, leider habe ich nicht mit Interrupt
> gefunden.

Aus gutem Grund. Denn während der Taster prellt, wird die ISR wiederholt 
aufgerufen. Niemand weiß wie oft und wie schnell hintereinander. Die 
Auswirkung auf andere laufende Prozesse ist damit nicht vorhersehbar.

Code, der sich unvorhersehbar verhält sollte man vermeiden.

von leo (Gast)


Lesenswert?

Martin M. schrieb:
> void Debounce4Int0()
> ...
>   Serial.print("---> ");

und ein weiteres DON'T: kein Serial usw. in Interruptroutinen.

leo

von c-hater (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:

> Denn während der Taster prellt, wird die ISR wiederholt
> aufgerufen.

Nicht, wenn man den Interrupt einfach in der ISR deaktiviert...

> Niemand weiß wie oft und wie schnell hintereinander.

Genau das weiß man dann 100%ig. Es passiert genau ein Mal und das 
nächste Mal frühestens dann, wenn man den Interrupt wieder aktiviert.

> Die
> Auswirkung auf andere laufende Prozesse ist damit nicht vorhersehbar.

Sind sie dann.

Aber klar: für Taster ist das Konzept natürlich fast nie sinnvoll, denn 
man muss ja irgendwann den Interrupt wieder aktivieren, braucht also 
doch wieder irgendwas mit einer Zeit.
Manchmal kann man allerdings die eigentliche Funktion der Anwendung für 
diesen Zweck benutzen. Typisch z.B.: Fernbedienung. Die Dauer des 
gesendeten Codes kann hier die Entprellzeit darstellen. Danach pollt man 
die Taste, wenn immer noch gedrückt, nochmal denselben Code senden 
(oder, je nach Protokoll, den Repeatcode), wenn nicht: Interrupt 
reaktivieren und pennen gehen.

Aber es gibt auch noch andere mechanische Kontakte als dämliche Taster, 
insbesondere z.B. Quadratur-Encoder. Bei denen gibt es, bedingt durch 
das Funktionsprinzip keine Notwendigkeit für eine zeitabhängige 
Entprellung und deswegen kann man hier das Konzept durchaus sinnvoll 
nutzen.

von Peter D. (peda)


Lesenswert?

Martin M. schrieb:
> Ich habe mir da was bebastelt schalte einfach den externen Interrupt für
> die Zahl X aus.

Das ist komplett ohne jeden Effekt, da innerhalb des Handlers die 
Interrupts eh gesperrt sind.
Du wirst schon noch merken, wenn die Tasten altern, daß Dein Code nichts 
taugt.

Etwas besser funktioniert Dein Code, wenn Du nach dem Delay vor dem Ende 
des Handlers das Interruptflag löschst (1 reinschreiben).

Das Delay in der leeren Loop hat ebenfalls keinen Effekt.

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
Noch kein Account? Hier anmelden.