Forum: Mikrocontroller und Digitale Elektronik Tasterentprellung Flankenerkennung: Warum kein delay notwendig?


von Michael (Gast)


Lesenswert?

Hallo,

ich grad ein kleines Problem damit die Tasterentprellung per 
Flankenerkennung aus folgendem Artikel richtig zu verstehen.
https://www.mikrocontroller.net/articles/Entprellung#Flankenerkennung

Warum ist bei dieser Methode kein delay notwendig?

Wenn der Controller schnell genug läuft um einen "ganzen Prellvorgang" 
abtasten zu können werden hier doch nach wie vor mehrere Tastendrücke 
erkannt oder?

von MaWin (Gast)


Lesenswert?

Michael schrieb:
> Warum ist bei dieser Methode kein delay notwendig?

Ist es:

"Die Entprellung geschieht dabei durch die ganze Laufzeit des 
Programms."

Die Funktion taster() wird also in der Programmhauptschleife eingesetzt, 
die eine Laufzeit passend zur Entprellung haben sollte oder mit einem 
Delay dahingehend verlangsamt werden sollte.
1
while(1)
2
{
3
4
    if(taster())
5
    { 
6
    }
7
    :
8
    _delay_ms(10);
9
}

von Thomas W. (powerrookie)


Lesenswert?

Ich behaupte das macht sie auch nicht.
Hier wird lediglich, wie in der Überschrift steht, die Flankenerkennung 
durchgeführt.

Für eine Software Entprellung fallen mir nur zwei möglichkeiten ein :

1. Per Delay eine gewisse "Prellzeit" warten.

2. Das Signal regelmässig abtasten und ab einer gewissen Schwellzeit 
davon ausgehen das dass Prellen vorbei ist.

3. Möglichkeit 2 mit dem Stoff der "Flankenerkennung" kombinieren.

von Michael (Gast)


Lesenswert?

MaWin schrieb:
> while(1)
> {
>
>     if(taster())
>     {
>     }
>     :
>     _delay_ms(10);
> }

So kann ich die Entprellung nachvolziehen. Vielleicht sollte man 
diesbezüglich im Artikel einen kleinen Hinweis einfügen!?

von Michael (Gast)


Lesenswert?

Thomas W. schrieb:
> Ich behaupte das macht sie auch nicht.
> Hier wird lediglich, wie in der Überschrift steht, die Flankenerkennung
> durchgeführt.

Der Code auf dem ich in meinem ersten Post verwiesen habe befindet sich 
allerdings im Artikel mit dem Titel "Entprellung". Daher wäre es meiner 
Meinung nach Sinnvoll das Kapitel um einen entsprechenden Hinweis zu 
ergänzen.

von Outi O. (outlaw)


Lesenswert?

Was spräche gegen eine Hardwareentprellung ??

Ok, etwas mehr Aufwand und mehr Kosten bei Massenproduktionen aber man 
könnte die Software damit entlasten und ggf. auch beschleunigen, falls 
nötig.

von Pandur S. (jetztnicht)


Lesenswert?

Ich mache die Entprellung mit einem Timer :

interrupt timer0-overflow() {
 ..reload timer fuer 10ms tick..
 timercame=1;
}

main ()
 timer=0;
 ..
 loop forever{
  if timercame==1 {
   ..
   if taste.. { .. }
  timer=0;
  }
 }

Dh der Softwareaufwand ist fast Null. Das per hardware zu schlagen ist 
eigentlich nicht moeglich.

von Outi O. (outlaw)


Lesenswert?

Das stimmt.

Die Timer Variante habe ich auch immer gemacht aber mit der 
Hardwarevariante wäre man softwareunabhängig und weniger fehleranfällig.

Aber trotzdem schön zu hören, warum man trotzdem auf Software greift und 
auf welche Art.

von Michael (Gast)


Lesenswert?

Outi O. schrieb:
> Was spräche gegen eine Hardwareentprellung ??
>
> Ok, etwas mehr Aufwand und mehr Kosten bei Massenproduktionen aber man
> könnte die Software damit entlasten und ggf. auch beschleunigen, falls
> nötig.

Es ging mir nicht darum die beste Methode zu finden. Ich wollte 
lediglich die oben genannte Variante korrekt verstehen und 
nachvollziehen können.

von MaWin (Gast)


Lesenswert?

Jetzt N. schrieb:
> Dh der Softwareaufwand ist fast Null.

Du hast keine einzige Zeile eingespart,
sondern musst zusätzlich den Hardware timer intialisieren, eine 
Interrupt-Routine schreiben, UND brauchst trotzdem denselben Aufwand in 
der Hauoptschleife, die auch nicht zu langsam sein darf, sonst reagiert 
deine Tastatur nicht.

So ist das also Unsinn.

Es können andere, zusätzlich Gründe dafür sprechen in der 
Programmhauptschleife einen festen Timertick auswerten zu können, aber 
bloss für die Tastaturabfrage lohnt das nicht.
1
 uint8_t tasten,gedrueckt;
2
 
3
 while(1)// die Programm-Hauptschleife
4
 {
5
   tasten=PIND; // 8 Taster auf ein mal, liefern 1 wenn gedrückt (sonst ~PIND)
6
   gedrueckt=tasten&~gedrueckt;
7
   if(gedrueckt&1)
8
   {
9
     // Taster 1 wurde gerade runtergedrückt, mach was
10
   }
11
   if(gedrueckt&2)
12
   {
13
     // Taster 2 wurde gerade runtergedrückt, mach was
14
   }
15
   // mach was sonst in der Programm-Hauptschleife passieren muß
16
   gedrueckt=tasten;
17
    _delay_ms(10); // damit sie bestimmt länger dauert als eventuelles Prellen
18
 }

von Peter D. (peda)


Lesenswert?

Michael schrieb:
> Warum ist bei dieser Methode kein delay notwendig?

"Die Entprellung geschieht dabei durch die ganze Laufzeit des 
Programms."

Und sowas ist absoluter Murks^3.

Kurze Laufzeiten muß man durch Delays auffüllen bzw. lange Laufzeiten 
lassen Drücke vergessen.
Man erlegt sich damit nur unnötige Einschränkungen auf, an die man 
ständig denken muß.
Ich will keine Nebeneffekte beachten müssen, sondern mich beim 
Programmieren voll auf die eigentliche Aufgabe konzentrieren können.

Man sollte immer Routinen bevorzugen, die sowenig wie möglich 
Seiteneffekte haben oder Vorbedingungen stellen.

von Pandur S. (jetztnicht)


Lesenswert?

mawin :
>Es können andere, zusätzlich Gründe dafür sprechen in der
Programmhauptschleife einen festen Timertick auswerten zu können, aber
bloss für die Tastaturabfrage lohnt das nicht.

Ich habe bei allen Anwendungen einen festen Tick. Wie soll man eine 
Controlleranwendung ohne Tick schreiben ? Denn delay() gibt es nicht. Es 
darf gar nirgends gewartet werden sonst wird man nie eine Echtzeit 
Performance erreichen.

von m.n. (Gast)


Lesenswert?

Peter D. schrieb:
> Man sollte immer Routinen bevorzugen, die sowenig wie möglich
> Seiteneffekte haben oder Vorbedingungen stellen.

Guter Vorschlag!
Hier wird nicht einmal ein Timer gebraucht: 
Beitrag "Re: EIN-AUS mit Taster per Interrupt, ATtiny25 o.ä."
;-)

von BirgerT (Gast)


Lesenswert?

Michael schrieb:
> Hallo,
>
> ich grad ein kleines Problem damit die Tasterentprellung per
> Flankenerkennung aus folgendem Artikel richtig zu verstehen.
> https://www.mikrocontroller.net/articles/Entprellung#Flankenerkennung
Genau ab dieser Stelle wird eine Funktion "taster" beschrieben, die aus 
einer anderen Funktion aufgerufen..
>
> Warum ist bei dieser Methode kein delay notwendig?
..das "delay" ist in der aufrufenden Funktion erforderlich..
>
> Wenn der Controller schnell genug läuft um einen "ganzen Prellvorgang"
> abtasten zu können werden hier doch nach wie vor mehrere Tastendrücke
> erkannt oder?
..yepp.

Alternativ kann man auch das Tastenbit in eine uint8_t Variable von 
recht nach links schieben:
1
uint8_t tastenstate = 0;
2
:
3
if(systemzeit >= Tastenabfragezeitpunkt) {
4
  tastenstate <<= 1;
5
  tastenstate |= TASTENPINBIT;  // ist 1, wenn Taster betätigt
6
  :
7
  switch (tastenstate & 0x03) {
8
  case 0: Zustand = NICHT_GEDRUECKT; break;
9
  case 1: Zustand = STEIGENDE_FLANKE; break; // wird gerade betätigt
10
  case 2: Zustand = FALLENDE_FLANKE; break;  // wird gerade losgelassen
11
  case 3: Zustand = GEDRUECKT; break;
12
  }
13
}
14
:
15
if (tastenstate > 0xfe) TASTE_KLEMMT; // ;-)

Es kommt auch immer darauf an, wie die Taste betätigt wird;
- ein von Hand betätigter Taster -> reicht den alle 100ms abzufragen,
- Tastimpuls von einem (mechanischen) Impulsgeber / (Reed)Relais -> 
mind. 10ms - 20ms Abfragezyklus.
- Optokoppler ? - Schaffste 'ne ms Schleifendurchlauf?

Einen mechanischen Taster auf einen INT Eingang zu packen, und in der 
ISR einen Zähler hochzählen ist nur etwas für delay()_Junkies..

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.