Taster Entprellen [Interrupt]

OP #3684672
Lesenswert?

Hallo liebe Community!:)

Ich habe hier mein erstes Script geschrieben, mit welchem man durch 
Tastendruck eine LED ein- bzw. ausschalten kann.
Jetzt habe ich das Problem, dass meine Taster "bouncen".
Habe mir schon mehrere Beiträge durchgelesen, jedoch meistens nicht 
genau verstanden oder die Beiträge waren mit Interrupts inkompatibel.
Könnte mir jemand eine gute Seite empfehlen oder mein Script 
vervollständigen und mir erklären welcher Befehl was macht?

Danke im Vorraus!:)

1
#include <avr/io.h>
2

3
#include <avr/interrupt.h>       // enthält alle Routinen
4
                                 //für die Interruptverarbeitung
5

6

7
                                 //ISR (Interrupt-Service-Routine) für
8
                                 //Interrupt 0
9
     
10
{
11
   PORTD |= (1<<PD7);            //setze PortD 7 (Lampe an)
12
}
13
 
14
                                  //ISR (Interrupt-Service-Routine) für 
15
                                  //Interrupt 1
16

17
{
18
   PORTD &= ~(1<<PD7);            //lösche PortD 7 (Lampe aus)
19
}
20

21

22
int main(void)
23
{
24
 DDRD |= (1<<PD7)
25
 PORTD|= (1<<PD2) | (1<<PD3)
26

27
 MCUCR |= (1<<ISC10) | (1<<ISC11); //Interrupt 1 wird konfigriert    
28

29
                                    //Interrupt 0 wird konfiguriert
30

31
  GICR |=(1<<INT0)  | (1<<INT1);     //INT0 und INT1 aktiviren
32

33
  sei();                             //Interrupts global aktivieren
34
  
35
  while(1)
36
  {
37

38
  }
39

40
}
Angehängte Dateien:
Gast #3684678
Lesenswert?

>Ich habe hier mein erstes Script geschrieben, ...
> ... mir erklären welcher Befehl was macht?

Unsinn, entweder selbst geschrieben, oder kopiert und nicht verstanden. 
Was nun?

Ließ doch mal hier das Tutorial zum Einlesen von Tasten.
OP #3684685
Lesenswert?

Ich habe das Script selber geschrieben und verstanden? Ich möchte nur 
eine Erklärung wie ich das "Entprellen" einbauen kann.
Das Problem ist ich soll das ganze in Scriptform abgeben mit Erklärung 
und allem, Teil 1 also Interrupts allgemein hab ich fertig, das 
Software Entprellen gäbe noch paar extra Punkte, deshalb würde ich das 
ganz gerne machen.
#3684695
Lesenswert?

Mit dem flankengesteuertem Interrupt kann man den Taster nicht gut 
entprellen, da jede Prell-Flanke ein Interrupt auslöst. Für gewöhnlich 
nimmt man ein Timer Interrupt und fragt den Zustand in der ISR ab.
Siehe --> Entprellung <--

Habe ich das richtig verstanden, dass du die LED mit einer Taste ein- 
und mit einer anderen ausschaltest, also wie ein RS-FlipFlop? Wenn ja 
ist entprellen nicht notwendig. Dein einziges Problem ist dass die ISR 
durch das Prellen öfters aufgerufen wird und Rechenzeit verbraucht. Das 
kannst du wenn du flankengesteuerte Interrupts verwendest nur in 
Hardware lösen.
OP #3684703
Lesenswert?

Stimmt wenn ich es genau überdenke ist ein Entprellen gar nicht 
notwendig.
Danke erstmal dafür :)

Ich würde jedoch gerne bei der Verwendung der externen Interrupts 
bleiben, ist es möglich den Taster so abzufragen das nach Betätigung die 
Interrupts global deaktiviert werden "cli();" und dann nach 100ms 
einfach wieder aktiviert werden "sei();". Wäre zwar keine genaue Methode 
aber für mich ausreichend.
#3684707
Lesenswert?

Schüler E. schrieb:
> ist es möglich den Taster so abzufragen das nach Betätigung die
> Interrupts global deaktiviert werden "cli();" und dann nach 100ms
> einfach wieder aktiviert werden "sei();"
Bitte komm NICHT auf die Idee ein Delay in die ISR zu stecken, das ist 
ein ABSOLUTES NO-GO. Du könntest es so machen, dass du in der ISR 
INT0/INT1 deaktivierst und einen Timer, der nach 100ms überläuft, 
startest und in der Timer ISR das entsprechende Interrupt wieder 
aktivierst.
Gast #3685014
Lesenswert?

Wozu der Timer? Wenn man separate Tasten fürs Ein- und Ausschalten hat, 
ist Entprellen nicht nötig, da immer nur die erste Flanke von genau 
einem Eingang interessiert.

Also:

Interrupt0:
 - Int.0 sperren
 - Licht an
 - Int.1 einschalten

Interrupt 1:
 - Int.1 sperren
 - Licht aus
 - Int.0 einschalten

Solange das Licht an ist, bekommt der Prozessor dann natürlich nicht 
mehr mit, wenn die Einschalttaste nochmal gedrückt wird (Interrupt 0 ist 
ja deaktiviert). Aber das macht nichts; der Prozessor würde ja sowieso 
nichts für den Benutzer wahrnehmbares tun.
#3685025
Lesenswert?

Nosnibor schrieb:
> Wozu der Timer? Wenn man separate Tasten fürs Ein- und Ausschalten hat,
> ist Entprellen nicht nötig, da immer nur die erste Flanke von genau
> einem Eingang interessiert.
>
> Also:
>
> Interrupt0:
>  - Int.0 sperren
>  - Licht an
>  - Int.1 einschalten
>
> Interrupt 1:
>  - Int.1 sperren
>  - Licht aus
>  - Int.0 einschalten
>

Und wenn man sich das mal genau überlegt, erhebt sich die Frage, wozu 
man da überhaupt externe Interrupts braucht.
Nur dazu, damit man eine Flankenerkennung gratis bekommt. Die ist aber 
so kompliziert auch wieder nicht. Und wenn es nur darum geht ein Licht 
mit 2 Tastern ein bzw. aus zu schalten, braucht man noch nicht mal das.

Alles was man braucht ist eine Variable, die festhält ob das Licht 
brennen soll oder nicht. Wobei man sogar die noch einsparen könnte, bzw. 
in das Bit des Portregisters legen kann, mit der die LED verbunden ist.
1
int main()
2
{
3
.....
4

5
  while( 1 )
6
  {
7
    if( !(PIND & ( 1 << PD0 )) )
8
      PORTB |= ( 1 << PB1 );
9

10
    if( !(PIND & ( 1 << PD1 )) )
11
      PORTB &= ~( 1 << PB1 );
12
  }
13
}

fettich.

Wobei: ordentliches Einlesen von Tastendrücken und deren Entprellung ist 
eine Technik, die man irgendwann sowieso braucht. Aber sicher nicht ...
1
... Ich habe hier mein erstes Script geschrieben.
... in dieser Situation. Tastendrücke zu erkennen (im Gegensatz zu 'ist 
eine Taste gedrückt') ist erstaunlicherweise nicht so einfach. Lediglich 
das Stichwort 'externer Interrupt' zu benutzen, greift da deutlich zu 
kurz.
Gast #3685045
Lesenswert?

> Interrupt0:
>  - Int.0 sperren
>  - Licht an
>  - Int.1 einschalten
>
> Interrupt 1:
>  - Int.1 sperren
>  - Licht aus
>  - Int.0 einschalten

Wenn die beide IRQ-Routinen schnell genug durchlaufen werden, dann sorgt 
eine lange Prellzeit dafür, dass das Ganze ein Zufallsgenerator ist 
(Licht ist AN oder AUS).
Gast #3685109
Lesenswert?

Karl-Otto schrieb:
> Wenn die beide IRQ-Routinen schnell genug durchlaufen werden, dann sorgt
> eine lange Prellzeit dafür, dass das Ganze ein Zufallsgenerator ist
> (Licht ist AN oder AUS).

Nur wenn der Benutzer beide Tasten gleichzeitig (im Sinne von: die 
zuerst gedrückte Taste prellt noch, während die zweite gedrückt wird) 
drückt.
Selber schuld, wenn er sich nicht entscheiden kann.
Gast #3685118
Lesenswert?

Auf alle Fälle ist es der Welt dümmster Ansatz, prellende Tasten per 
Interrupt zu behandeln.
Würd ich meinem Lehrer sagen und auch begründen können.

Haben die denn keine besseren Beispiele parat, wenn die Behandlung von 
Interrupts im Unterricht besprochen wird????
#3685858
Lesenswert?

Ich habe das grade mal probiert und kann bestätigen - per Interrupt 
Taster entprellen ist eine schlechte Idee. Habe das jetzt so weit 
getrieben:
- Interrupt auf steigende Flanke an PinB3 (Taster zieht mit 150Ohm auf 
Vcc; Pin hat 10k Pulldown auf GND).
- Erste Schnellschussfassung: Bis 3 zählen (also 3 Interrupts abwarten) 
und erst das als Tastendruck erkennen. Kommt bei etwa 75% der 
Tastendrücke hin. Aber immer noch ein ziemlicher Zufallsgenerator.
- Ich merke mir TasteGedrückt beim ersten Druck, werfe einen Timer an 
und in dessen ISR führe ich meine Sachen aus. Dazu deaktiviere ich die 
erste Interrupt-Routine. Idee: damit warte ich das Prellen einfach ab.
Ist aber ein viel schlimmerer Zufallsgenerator; erzeugt immer 2-3 
erkannte Tastendrücke, die dann nach der Wartezeit ausgeführt werden. 
Hätte gedacht, dass die durch das Deaktivieren des ISR nicht aufgenommen 
würden, war aber nichts.

Ich glaube so langsam, entprellen in Software ist doch nicht trivial ;)

Ich brauche die Interrupts, weil mein Programm weiterlaufen und der 
Prozessor in einer Stellung sogar im Powerdown schlafen soll (Strom 
sparen). Per ISR geht das, und der Prozi wird wieder geweckt.
#3686077
Lesenswert?

Dirk K. schrieb:
> Ich brauche die Interrupts, weil mein Programm weiterlaufen und der
> Prozessor in einer Stellung sogar im Powerdown schlafen soll (Strom
> sparen). Per ISR geht das, und der Prozi wird wieder geweckt.

Zum Aufwachen ist der Interrupt geeignet. Danach wird dann normal 
entprellt.
Programmfunktion und Sleepmode/Aufwachen sind quasi 2 eigenständige 
Tasks, die man auch getrennt entwickelt:

Beitrag "AVR Sleep Mode / Knight Rider"
#3686161
Lesenswert?

Peter II schrieb:
> Teo Derix schrieb:
>> aber auch nicht vergessen das Taster auch beim loslassen prellen
>> können!
>
> wie kann man sich der erklären?

Wie beim Dribbeln, Du schlägst auf den Ball und er kehrt wieder zur Hand 
zurück.
Die Kontaktfeder speichert beim Betätigen Energie und gibt sie als 
gedämpfte Schwingung ab.

Bei Tasten ohne Schnappmechanik (Druckpunkt) kann auch Deine 
Muskelbewegung eine Mehrfachbetätigung auslösen. Muskeln werden ja 
gepulst.
#3686176
Lesenswert?

Peter II schrieb:
> Peter Dannegger schrieb:
>> Wie beim Dribbeln, Du schlägst auf den Ball und er kehrt wieder zur Hand
>> zurück.
>> Die Kontaktfeder speichert beim Betätigen Energie und gibt sie als
>> gedämpfte Schwingung ab.
>
> schon klar, aber sie schwinkt doch wohl nie so stark das sich die
> kontakte wieder verbinden.

Wenn du Kontakte stark genug abgenudelt sind, kann alles mögliche 
passieren.
Mit der PeDa Entprellung ist das ja kein Problem. Die entprellt in 
beiden Richtungen.
#3686189
Lesenswert?

Peter II schrieb:
> schon klar, aber sie schwinkt doch wohl nie so stark das sich die
> kontakte wieder verbinden.

Ist eine Frage der Konstruktion. Die Schnappmechanik speichert deutlich 
mehr Energie, als für das reine Bewegen der Kontaktfeder nötig ist.
Zusätzlich werden Taster immer kleiner (billiger), d.h. kleiner 
Kontaktabstand, kleine Federn. Die Betätigungskraft des Menschen bleibt 
aber gleich.

Ein weiterer Prellgrund, Tasten altern, d.h. es bilden sich kleine 
isolierende Bereiche (Staub, Oxydschicht) die beim darüber Bewegen den 
Strom unterbrechen.

Das Heimtückische am fehlenden Enprellen ist, daß fabrikneue Tasten oft 
kaum prellen. Und nach einem halben Jahr Benutzung geht dann das Drama 
los.
#3686218
Lesenswert?

Peter Dannegger schrieb:
> Programmfunktion und Sleepmode/Aufwachen sind quasi 2 eigenständige
> Tasks, die man auch getrennt entwickelt:

Darüber hatte ich nur kurz sinniert und bin noch zu keiner für mich 
schlüssigen Umsetzung gekommen (Programm ist wie ein Artikel für mich: 
Der muss im Kopf fertig sein und wird dann nur noch am Ende auf Papier 
geworfen.)

Danke für den Tipp, war die Richtung also gar nicht so verkehrt. Werde 
das mal umsetzen - ist zwar nur ein Lernstück für mich selber (quasi ein 
LED-Throwie mit RGB-LED und Taster an 'nem ATtiny85 mit Speisung aus 
CR2032), aber genau diesen Zweck (lernen, Probleme machen) erfüllt es 
trotz eigentlich größter Simplizität hervorragend.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren