Forum: Mikrocontroller und Digitale Elektronik Taster entprellen


von Stefan Mayerhofer (Gast)


Lesenswert?

Hallo Leute,

Ich weiß es gibt viele Tutorials zum Taster entprellen jedoch will ich 
nicht blind was kopieren oder auswendig lernen sondern es selber 
schreiben und wirklich durchdenken.

Meiner Meinung nach ist mein Programm genau das was es sein soll, jedoch 
leuchtet die LED einfach nicht auf. Schon langsam gebe ich auf.
Könnt ihr mal drüberschauen und mir eventuelle einen Denkstoss 
verpassen?
Schaltung ist nur eine LED mit Vorwiderstand auf Pin 7,mehr nicht. Bin 
Anfänger und beginne eben nur mit ner LED jedoch schreibe ich immer 
verschiedene Programme dafür (Ext.Interrupt, PWM,..)


Das hier wäre mein Code:
_____________________________________________
volatile int y=0,x=0,z=0;
boolean ledstatus=LOW;

void setup()

{
 pinMode(2,INPUT);
 pinMode(7,OUTPUT);

}

void loop()

{

 y=digitalRead(2);

 if(y>0)
 {
  x=millis();
  if((millis()-x)>50)
  {
    if(y>0)
    {
      ledstatus=HIGH;
    }
  }
 }
 else if (y==0)
 {
 ledstatus=LOW;
 }
 digitalWrite(7,ledstatus);

}
____________________________________________________

Pin 2 hat einen Pull Down Widerstand.

Bin für jede Kritik dankbar.

Lg Stefan

von Dietrich L. (dietrichl)


Lesenswert?

Stefan Mayerhofer schrieb:
>   x=millis();
>   if((millis()-x)>50)

So wie ich das sehe ist diese Bedingung nie erfüllt.

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Stefan Mayerhofer schrieb:
> x=millis();
>   if((millis()-x)>50)
>   {
>     if(y>0)
>     {
>       ledstatus=HIGH;
>     }
>   }
>  }


Sieh Die mal die ersten beiden Zeilen an.

x wird der aktuelle Wert von "millis()" zugewiesen.

Unmittelbar danach wird geprüft, ob der Wert x um mehr als 50 vom 
aktuellen Wert von "millis()" abweicht.

Wie soll das funktionieren? Dein µC ist nicht so langsam, daß er für 
zwei unmittelbar aufeinanderfolgende Operationen mehr als 50 
Millisekunden benötigt.

von Stefan F. (Gast)


Lesenswert?

Den gleichen Fehler hatte jemand anderes hier schon vor wenigen Tagen.
Beitrag "Arduino Millis"
Dort findest du auch Korrekturvorschläge.

von Stefan Mayerhofer (Gast)


Lesenswert?

Komischer Weise wenn ich das Programm am Arduino so stehen lasse für 
einige Zeit dann leuchte die LED iergendwann mal auf also kommt es doch 
iergendwie in die if-Abfrage rein.

Ich überreisse es einfach nicht :/

von Stefan F. (Gast)


Lesenswert?

> Ich überreisse es einfach nicht

Welches Arduino Modul verwendest du denn?

Wenn es eins mit im µC integriertem USB oder WLAN ist, kann das schon 
sein, denn diese unterbrechen den normalen Programmablauf zyklisch um 
die Schnittstellen zu bedienen.

von Dietrich L. (dietrichl)


Lesenswert?

Stefan Mayerhofer schrieb:
> Komischer Weise wenn ich das Programm am Arduino so stehen lasse für
> einige Zeit dann leuchte die LED iergendwann mal auf also kommt es doch
> iergendwie in die if-Abfrage rein.

Vermutung: wenn millis() zwischen den 2 Abfragen überläuft.

von Stefan Mayerhofer (Gast)


Lesenswert?

Einen Arduino UNO.

lg

von Stefan F. (Gast)


Lesenswert?

> Vermutung: wenn millis() zwischen den 2 Abfragen überläuft.

Kann auch sein. Wenn die Variable x vom gleichen Typ wäre, wie das 
Ergebnis von millis() würde der Überlauf allerdings keine Fehlfunktion 
auslösen. Um das zu erklären, muss man sich ganz genau anschauen, was 
die Subtraktion in diesem Fall mit den Bits anstellt.

von Rolf M. (rmagnus)


Lesenswert?

Dietrich L. schrieb:
> Vermutung: wenn millis() zwischen den 2 Abfragen überläuft.

Bzw. x. Denn es ist ja nur 16 Bit breit und vorzeichenbehaftet, also 
wird es nach ca. 32 Sekunden negativ.

von Stefan Mayerhofer (Gast)


Lesenswert?

Hat wer eine Lösung ?

von Stefan F. (Gast)


Lesenswert?

> Hat wer eine Lösung ?

Sehr lustig, voll der Schenkelklopfer!

von Stefan Mayerhofer (Gast)


Lesenswert?

I know I know, für euch ist mein Problem lustig jedoch ist es für mich 
zurzeit eine richtige Herausforderung :/

von Stefan F. (Gast)


Lesenswert?

Dann lies den Thread, auf den ich verwiesen habe. Dort steht die Lösung.

Falls du den nicht verstehst, melde Doch hier nochmal. Dann müssen wir 
nämlich ganz unten bei den allerersten Grundlagen anfangen. Die wären:

- wann und wie oft wird setup() ausgeführt?
- wann und wie oft wird loop() ausgeführt?
- was macht millis()?
- was ist der Unterschied zwischen einer Schleife und einer Bedingung?
- Welche Datentypen stehen zur Verfügung?

Das steht aber auch alles in den Arduino Tutorials, man muss sie nur 
lesen. Die sind schon sehr kurz gehalten, extra für Leute, die nicht 
gerne lesen.

von Dietrich L. (dietrichl)


Lesenswert?

Stefan Mayerhofer schrieb:
> I know I know, für euch ist mein Problem lustig jedoch ist es für mich
> zurzeit eine richtige Herausforderung :/

Du willst ja lernen, daher:
Ich empfehle, erst einmal ein Flußdiagramm zu zeichnen, wie du dir den 
Ablauf denkst.
Als zweiter Schritt käme dann die Umsetzung in den Code.

von Stefan Mayerhofer (Gast)


Lesenswert?

Den Thread habe ich gelesen und den verstehe ich, dieser soll eine LED 
zum BLinken bringen und da speichert man den millis Wert in eine 
Variable und diese Variable fragt man danach ab und toogelt.

Hier kann ich ja den millis Wert nach der if-Abfrage nicht abspeichern 
weil ja dieser danach viel kleiner ist als der jetzige wenn ich die 
taste drücke, da komm ich ja immer wieder in die if Abfrage rein du das 
Entprellen ist weg.

von Stefan F. (Gast)


Lesenswert?

> Hier kann ich ja den millis Wert nach der if-Abfrage nicht
> abspeichern weil ja dieser danach viel kleiner ist als der jetzige

>> was macht millis()?

von Stefan Mayerhofer (Gast)


Lesenswert?

Millis gibt dir die Zeit an seit dem das Programm läuft...

von Stefan F. (Gast)


Lesenswert?

Genau, und deswegen kann millis() nicht kleiner werden (angesehen von 
dem sehr seltenen Überlauf, der aber bei der Subtraktion zum Glück 
keinen Fehler auslöst).

Du willst die LED einschalten, wenn der Taster mindestens 50ms lang 
gedrückt wurde. Also:
1
unsigned long sperrzeit=0;
2
3
void loop()
4
{
5
    if (!digitalRead(2))
6
    {
7
        // Taste wurde losgelassen oder prellt
8
        sperrzeit=millis();
9
        // LED aus
10
        digitalWrite(7,LOW);
11
    }
12
    else if (millis()-sperrzeit > 50)
13
    {
14
        // Taste wurde lange genug gedrückt
15
        // LED an
16
        digitalWrite(7,HIGH);
17
    }
18
}

von Einer K. (Gast)


Lesenswert?

Stefan Mayerhofer schrieb:
> Den Thread habe ich gelesen..

Ein Entpreller mit dem Code aus: 
Beitrag "Re: Arduino Millis"

1
#include <CombieTimer.h>
2
3
Combie::Timer::EntprellTimer entprellen(100); // Entpreller Instanz erzeugen
4
5
6
const byte taster =  2;
7
const byte led    = 13;
8
9
10
void setup()
11
{
12
 pinMode(taster,INPUT);
13
 pinMode(led   ,OUTPUT);
14
}
15
16
void loop()
17
{
18
  digitalWrite(led,entprellen(digitalRead(taster)));
19
}


Ich erwarte nicht, dass du ihn vollständig verstehst. Aber hoffe, dass 
du etwas daraus mitnehmen kannst.
z.B: Das man sich mit komplizierten if, und ihren Bedingungen, selber 
eine Frikadelle ans Knie nagelt.

von Stefan F. (Gast)


Lesenswert?

> Das man sich mit komplizierten if, und ihren Bedingungen,
> selber eine Frikadelle ans Knie nagelt.

Ah ja, und was finden wir in der Datei CombieTimer.h? Komplizierte if 
Bedingungen! Und dann auch noch den kompletten Quelltext in der *.h, das 
ist definitiv nichts, was man Anfängern empfehlen sollte.

Dann wird dort der () Operator überladen, da muss man erstmal drauf 
kommen!

Der TO wollte keine fertige Klasse verwenden, sondern lernen, wie es 
funktioniert.

von Stefan Mayerhofer (Gast)


Lesenswert?

Danke dir,

Kann ich meinen Code umschreiben, deinen verstehe ich nur teilweise.

Bei der else if Abfrage kommt ja kein (digitalRead(2)==HIGH)) , wie soll 
der dann hier reinkommen.

Ich mein es funkt, habs auspobiert, jedoch hab ichs nicht zur Gänze 
kapiert.

von Einer K. (Gast)


Lesenswert?

Stefan U. schrieb:
> Ah ja, und was finden wir in der Datei CombieTimer.h? Komplizierte if
> Bedingungen!
3 IF Bedingungen

> if(!abgelaufen)
und
> if(merker == trigger)
> if(timer(entprellzeit))

Das sind drei einfache Bedingungen.
Und nicht verschachtelt.

Das ist dir also schon zu kompliziert....
Aha, ja...

Des weiteren, im Gegensatz zum Code des TE, deutlich benannte Variablen.

Stefan U. schrieb:
> Und dann auch noch den kompletten Quelltext in der *.h,
Was gibts dagegen einzuwenden?
Als Arduino User hat man dauernd damit zu tun.
Viele Libs sind so aufgebaut.

Stefan U. schrieb:
> Der TO wollte keine fertige Klasse verwenden, um zu lernen, wie es
> funktioniert.
Sicher!

Darum sagt er ja auch:
Stefan Mayerhofer schrieb:
> Hat wer eine Lösung ?
Das ist die Lösung welche ich bieten kann.
Entweder lernt er was draus, oder er verwirft sie.
Ist mir beides recht.


Übrigens, ich halte es für eine echt doofe Idee, Arduino Anfänger vor 
der OOP beschützen zu wollen.
Denn:
Als Arduino User hat man dauernd damit zu tun.
Viele Libs sind so aufgebaut.

von Stefan F. (Gast)


Lesenswert?

> Kann ich meinen Code umschreiben, deinen verstehe ich nur teilweise.

Offensichtlich kannst du deinen Code nicht umschreiben, weil du weder 
deinen noch meinen verstanden hast. Wir helfen Sir gerne, aber dazu 
musst du konkrete Fragen stellen und wenigstens die Grundlagen der 
Programmiersprache gelernt haben.

> Bei der else if Abfrage kommt ja kein (digitalRead(2)==HIGH)),
> wie soll der dann hier reinkommen.

Ich verstehe diesen Satz nicht. Wer soll wo rein kommen?

Was glaubst du denn, was digitalRead(2) liefert?
Und was erwartet if() zwischen den Klammern?

Welche Ausdrücke/Werte gelten als wahr?

von Einer K. (Gast)


Lesenswert?

Stefan Mayerhofer schrieb:
> Bei der else if Abfrage kommt ja kein (digitalRead(2)==HIGH)) , wie soll
> der dann hier reinkommen.

(digitalRead(2)==HIGH)
Ist das gleiche wie:
digitalRead(2)

Das ==HIGH ist an der Stelle flüssiger wie Wasser.
Überflüssig.

von Stefan Mayerhofer (Gast)


Lesenswert?

Ok also, DU fragst ab Wenn der Taster nicht gedrückt ist 
(if(!digitalRead(2))
soll die Lampe aus sein. Millis wird hier dauernd in die Sperrzeit 
geschrieben.

So, ich drücke nun den Taster und da häng ich wieder. Es steht niergends 
eine Abfrage was ist wenn der Taster gedrückt wird. Was ich aber 
verstehe ist das wenn der Taster prellt die if Abfragen nacheinander 
aufgerufen werden.



Bitte erkläre mir deinen Code.

von Einer K. (Gast)


Lesenswert?

Ist doch recht einfach...

Wenn die Taste NICHT gedrückt ist, wird sich die Sperrzeit gemerkt und 
die led aus gemacht.
Wenn die Taste gedrückt ist, wird geprüft, ob die 50ms abgelaufen sind, 
und dann die LED angemacht.

Der Code wird auf einem UNO ca 100000 mal pro Sekunde durchlaufen.

von Stefan F. (Gast)


Lesenswert?

> Es steht niergends eine Abfrage was ist wenn der Taster gedrückt wird.

Doch, das ist der "else" Teil. Und an den habe ich direkt die nächste 
Bedingung angehängt.
1
unsigned long sperrzeit=0;
2
3
void loop()
4
{
5
    if (!digitalRead(2)) // Wenn die Taste nicht gedrückt ist ...
6
    {
7
        // Taste wurde losgelassen oder prellt
8
9
        // Messung der Sperrzeit erneut beginnen
10
        sperrzeit=millis();
11
12
        // LED aus
13
        digitalWrite(7,LOW);
14
    }
15
    else // ansonsten (also wenn die Taste gedrückt ist)...
16
    if (millis()-sperrzeit > 50) // Wenn die Sperrzeit überschritten wurde
17
    {
18
        // Taste wurde lange genug gedrückt
19
        // LED an
20
        digitalWrite(7,HIGH);
21
    }
22
}

Mit if und else if kann man beliebig lange Ketten bauen.
1
if (geld<10)
2
  puts("ich bin bettelarm, denn ich habe weniger als 10 Euro");
3
else if (geld<100)
4
  puts("ich kann was zum essen kaufen, denn ich habe 10 bis 99,99 Euro");
5
else if (geld<500)
6
  puts("ich kann ins Restaurant gehen, denn ich habe 100 bis 499,99 Euro");
7
else 
8
  puts("Es reicht sogar für ein neue Fahrrad, denn ich habe mindestens 500 Euro");

Wie gesagt: Grundlagen der Programmiersprache lernen.
https://www.arduino.cc/reference/en/

https://www.arduino.cc/reference/en/language/structure/control-structure/if/
Hier müsste eigentlich if..else erkläert sein, aber irgendwie haben sie 
bei if aufgehört zu schreiben. Das ist ja mies.

Vielleicht ist eine Grundlagen-Doku abseits von Arduino doch besser: 
http://www.c-howto.de/tutorial/

von Einer K. (Gast)


Lesenswert?

Stefan U. schrieb:
> Hier müsste eigentlich if..else erkläert sein, aber irgendwie haben sie
> bei if aufgehört zu schreiben.
Die C++ Grundlagen muss man aus anderen Quellen beziehen.

Würde auch keinen Sinn machen die C++ Bücher abzuschreiben und auf der 
Arduino Seite zu publizieren. Denn das Netz und die Büchereien sind voll 
mit C++ Tutorials.

Außerdem ist das ein Wiki System, kein Selbstbedienungsladen ohne Kasse, 
da beschwert man sich nicht über Unvollständigkeit, sondern erweitert 
die Doku.

Merksatz:
Kritik an anderen, schützt nicht davor, eigene Leistung bringen zu 
müssen..

von Echter Nordhäuser (Gast)


Lesenswert?

Stefan schrieb:
> Mit if und else if kann man beliebig lange Ketten bauen.

Gibt es denn in dieser Supersprache kein "Select-Case" Konstrukt?
Wenn hier mehr als 3 Sachen zu unterscheiden sind, beißt der 
Programmierer doch zwischenzeitlich die Tastatur in Stücke.

von Stefan F. (Gast)


Lesenswert?

> Gibt es denn in dieser Supersprache kein "Select-Case" Konstrukt?

Doch schon (switch-case) aber das kann nur auf Gleichheit mit Konstanten 
vergleichen, nicht größer oder kleiner als.

> Wenn hier mehr als 3 Sachen zu unterscheiden sind

Nur eine Sprache, nämlich C++. Da C++ jedoch eine Erweiterung von C ist, 
genügt es für den TO momentan, die Grundlagen also C zu lernen.

von Mike1996 (Gast)


Lesenswert?

Nur eine Idee von mir, wie wäre dieser Code um das Prellen zu entgehen?

Tastergedrückt=DigitalRead(Pin1);

If(tastergedrückt)
{
    DigitalWrite(Pin2,High);
  Variable=1;
}

  If (variable==1&&tastergedrückt==0)
//fals prellen auftritt und wieder auf Masse gezogen wird
     {
      DigitalWrite (pin2,High)
      Variable=0;
     }




Else
DigitalWrite(Pin2,Low);

von Stefan F. (Gast)


Lesenswert?

Das ist total quatsch, völlig vorbei an der Aufgabe.

von Ray M. (ray_m)


Lesenswert?

1
volatile int taster_value = 0; // 0 = nix gedrückt
2
3
#define DP_BUTTON ???
4
5
void taster_isr() {
6
    long int c = 0;
7
    noInterrupts();
8
    while ( digitalRead(DP_BUTTON) == LOW ) {
9
        c++;
10
        delay(30);
11
    }
12
    taster_value = c;
13
    digitalWrite(DP_BUTTON, HIGH);
14
    interrupts();
15
}
16
17
void workOnKeyPress() {
18
    if ( taster_value != 0 ) {
19
        if ( taster_value < 15  ) { // short press
20
           ...
21
        } else if ( taster_value > 15 && taster_value < 50 ) {  // long press
22
           ...
23
        } else if ( taster_value > 50 ) {  // long long press
24
           ...
25
        } else {  // very long press
26
           ...
27
        }
28
        taster_value = 0; // reset taster state
29
    }
30
}
31
32
void initPushSwitch() {
33
    // for push switch handling
34
    pinMode(DP_BUTTON, INPUT);
35
    digitalWrite(DP_BUTTON, HIGH);
36
    attachInterrupt(DP_BUTTON, taster_isr, FALLING);
37
}
38
39
void setup() {
40
    ...
41
    initPushSwitch();   // init push switch handling (isr)
42
    ...
43
}
44
45
void loop() {
46
    ...
47
    workOnKeyPress(); // processing push switch
48
    ...
49
}

nachteil: reagiert erst wenn du den taster los lässt

: Bearbeitet durch User
von Mike1996 (Gast)


Lesenswert?

Warum ?

von Ray M. (ray_m)


Lesenswert?

Mike1996 schrieb:
> Warum ?

was ?

von Mike1996 (Gast)


Lesenswert?

Warum ist das falsch ?

von Stefan F. (Gast)


Lesenswert?

> Warum ist das falsch ?
Weil dein Code nicht entprellt. Das fehlt ganz offensichtlich das 
Abwarten einer gewissen Zeit.

von Mike1996 (Gast)


Lesenswert?

Wieso, wenns prellt dann wirds trotzdem auf high gezogen ?

von Stefan F. (Gast)


Lesenswert?

> Wieso, wenns prellt dann wirds trotzdem auf high gezogen ?

Genau ein mal. Prellt dein Taster immer nur einmal? Oder prellt er eine 
gewisse Zeit?

von Mike1996 (Gast)


Lesenswert?

Die variable wird ja immer wieder von 0 auf 1 und umgekehrt gesetzt 
dadurch kommts mal in die eine if und mal in die andere if. Ich bin über 
jede kritik dankbar, das es perfekt ist kann ich selber nicht sagen, 
aber ein vorschlag wärs halt gewesen.

von Einer K. (Gast)


Lesenswert?

Ray M. schrieb:
> delay(30);
Ein Irrweg.

Das Delay in der ISR wird das ganze System zum erliegen zwingen.

von gu (Gast)


Lesenswert?

und ???
die while-schleife auch ... und zwar genau
solange wie du auf den knopf drückst ...

wenn dir das delay() da nicht gefällt lass es weg
und mach die zahlen in workOnKeyPress() größer

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Stefan Mayerhofer schrieb:
> Das hier wäre mein Code:
Da könntest du die c-Tags drumrum machen, so wie es ein paar Zeilen über 
jeder Eingabebox beschrieben ist...

Stefan U. schrieb:
>> Vermutung: wenn millis() zwischen den 2 Abfragen überläuft.
> Wenn die Variable x vom gleichen Typ wäre, wie das Ergebnis von millis()
> würde der Überlauf allerdings keine Fehlfunktion auslösen.
millis() selber hat einen unsigned long, der läuft erst nach 49 Tagen 
über. Aber x ist leider nur ein 16 Bit int, da passiert der Überlauf 
schon nach 65 Sekunden...

Ray M. schrieb:
1
 void taster_isr() {
2
     long int c = 0;
3
     noInterrupts();
4
     while ( digitalRead(DP_BUTTON) == LOW ) {
5
         c++;
6
         delay(30);
In einer ISR darf niemals (ich wiederhole in Worten: nie, auf keinen 
Fall, garantiert nicht) ein delay() vorkommen. Nie!
Denn das sorgt dafür, dass andere Interrups nicht abgearbeitet werden 
können und z.B. eine serielle Schnittstelle einfach überfahren wird. 
Auch bei Timern kann es Probleme geben, wenn ihre Interrupts für solch 
lange Zeit blockiert werden.
Und im speziellen Code hier wird sogar das komplette System während des 
gesamten Tasterdrucks blockiert. Schlimmer gehts nimmer!

Stefan Mayerhofer schrieb:
> jedoch will ich nicht blind was kopieren oder auswendig lernen sondern
> es selber schreiben und wirklich durchdenken.
Eine brauchbare Entprellung ist in einem MAX6816 realisiert:
https://datasheets.maximintegrated.com/en/ds/1896.pdf
Und jetzt muss der Programmierer, der durch eigenes Nachdenken auf eine 
gleich gute Lösung kommen will, einfach mal einen halben Tag über 
"Figure 1. Block Diagram" grübeln und das in ein Programm umsetzen.
Wenn er es dann letztlich doch nicht hinbekommen hat und auch die vielen 
andren Threads zum Thema nicht zur Erleuchtung beigetragen haben, dann 
kann er ja immer noch einfach genau diesen MAX6816 kaufen und hat damit 
eine zuverlässig funktionierende Entprellung in seinem System.
https://www.reichelt.de/ICs-MAX-1000-9201/MAX-6816-EUST/3/index.html?ACTION=3&GROUPID=5470&ARTICLE=148598

> jedoch will ich nicht blind was kopieren oder auswendig lernen sondern
> es selber schreiben und wirklich durchdenken.
Wie wäre es, wenn du die Reihenfolge von Schreiben und Durchdenken 
umdrehst?
Du darfst auch gern anderen Code ansehen und analysieren. Du wirst 
dann z.B. sehen, dass der geniale Code von Peter Dannegger prinzipiell 
genauso funktioniert wie der obige MAX6816. Wenn du das erkannt hast, 
dann bist du mit dem Denken fertig und kannst loslegen mit dem 
Schreiben.
Als Denkhilfe ist recht brauchbar auch der Artikel Entprellung

: Bearbeitet durch Moderator
von Der Andere (Gast)


Lesenswert?


von Ray M. (ray_m)


Lesenswert?

Lothar M. schrieb:
>
> Ray M. schrieb:
>
1
>  void taster_isr() {
2
>      long int c = 0;
3
>      noInterrupts();
4
>      while ( digitalRead(DP_BUTTON) == LOW ) {
5
>          c++;
6
>          delay(30);
7
>
> In einer ISR darf niemals (ich wiederhole in Worten: nie, auf keinen
> Fall, garantiert nicht) ein delay() vorkommen. Nie!
> Denn das sorgt dafür, dass andere Interrups nicht abgearbeitet werden
> können und z.B. eine serielle Schnittstelle einfach überfahren wird.
> Auch bei Timern kann es Probleme geben, wenn ihre Interrupts für solch
> lange Zeit blockiert werden.
> Und im speziellen Code hier wird sogar das komplette System während des
> gesamten Tasterdrucks blockiert. Schlimmer gehts nimmer!

und ich hab gesagt dann lass den delay() einfach weg wenn er euch stört

für mich funktioniert das in 99% aller projekte, auch wenn die
isr natürlich alle anderen aktionen während das taster-drückens
blockiert, das delay() ist da gar kein problem weil eh noch 
noInterrupts()
steht !!! damit passiert während des taster-drückens nix anderes mehr

und ja, die lösung mit dem max ist natürlich schöner ;)

von Mike1996 (Gast)


Lesenswert?

Guten Morgen,

Ist mein Code also nicht vernünftig ?

Lg

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ray M. schrieb:
> für mich funktioniert das in 99% aller projekte, auch wenn die
> isr natürlich alle anderen aktionen während das taster-drückens blockiert
Alle Timer-Überläufe und sämtliche Schnittstellen und alle Interrupts. 
Na toll, solche Geräte kenne ich. Für mich "funktionert" so ein 
offensichtlich dahingehacktes Programm bestenfalls, wenn es für diesen 
Controller nur einzig und allein um diese Taste geht und der sonst 
nichts zu tun hat.

> und ja, die lösung mit dem max ist natürlich schöner
Und noch schöner ist Peter Danneggers Code, weil er zwar nicht bis 63 
zählt, sondern nur bis 3, das aber parallel für 8 Tasten in 2 Bytes.

: Bearbeitet durch Moderator
von Peter D. (peda)


Lesenswert?

Stefan Mayerhofer schrieb:
> Ich weiß es gibt viele Tutorials zum Taster entprellen jedoch will ich
> nicht blind was kopieren oder auswendig lernen sondern es selber
> schreiben und wirklich durchdenken.

Eine Entprellung besteht aus einem Integrator gefolgt von einem 
Schmitt-Trigger.
In Software macht man dazu einen gleitenden Mittelwert über z.B. 4 
Abtastungen. Das Abtastintervall wählt man größer als die Prellperiode, 
aber nicht so groß, daß der Nutzer eine Verzögerung merkt (typisch 
2..50ms). 4 aufeinanderfolgende Einsen werden dann als 1 interpretiert, 
4 aufeinanderfolgenden Nullen als 0. Alle anderen Muster bewirken keine 
Zustandsänderung. Fertig ist die Entprellung.

von Mike1996 (Gast)


Lesenswert?

Ich habe es versucht Hardwaremäßig zu entprellen und es hat nicht 
geklappt.

Hab auch einen Pull-Down Widerstand am Pin.
Hab parallel zum Pull Down einen 10uF Elko geschaltet und es hat sich 
kaum was verändert. Hab nähmlich per Serial Print mir eine Variable 
angeschaut die beim Tastendruck hinaufgezählt wird, bei einem 
Tasterdruck war die Variable größer als 30 also null entprellung. Kann 
ich da noch was machen, noch einen zusätzlichen Widerstand damit sich 
der Elko langsamer entlädt bzw. aufladet ?

Mein Widerstand beträgt 10kOhm.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Mike1996 schrieb:
> Ist mein Code also nicht vernünftig ?
Was heißt in Bezug auf Code "vernünftig"?
Er funktioniert halt einfach nicht, weil die Variable einfach um 1 
Schleifenzyklus und der Ausgang asymmetrisch um 2 Schleifendurchläufe 
versetzt dem Prellen folgt. Probiers aus...

Mike1996 schrieb:
> Nur eine Idee von mir, wie wäre dieser Code um das Prellen zu entgehen?
Wie gesagt: am Besten vor dem Schreiben drüber nachdenken, ob das 
überhaupt funktioniert?

von Mike1996 (Gast)


Lesenswert?

1
+5V
2
 |
3
 | 
4
 /
5
 |------
6
 |     |
7
 |    ---  
8
| |   ---
9
| |    |
10
 |     |
11
---   ---
Widerstnad 10kOhm, 10uF der Elko.

: Bearbeitet durch Moderator
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Mike1996 schrieb:
> Widerstnad 10kOhm, 10uF der Elko.
Warum ein Pulldown, wenn der uC schon einen Pullup hat?
Mit dieser Beschaltung funktionert Entprellen nur mäßig und nur, wenn 
der µC Schmitttrigger-Eingänge hat.

Mike1996 schrieb:
> Hab nähmlich per Serial Print mir eine Variable angeschaut die beim
> Tastendruck hinaufgezählt wird
Lass mal das Programm sehen...

BTW: für (d)eine neue Frage solltst du (d)einen neuen Thread beginnen. 
Und nicht den eines anderen kapern!

: Bearbeitet durch Moderator
von Hubert G. (hubertg)


Lesenswert?

Mike1996 schrieb:
> Widerstnad 10kOhm, 10uF der Elko.

Bei dem Konstrukt ist die Wahrscheinlichkeit sehr groß, das erstens der 
Taster nicht lange hält, zweitens der Kontroller undefiniert reagiert.

von Einer K. (Gast)


Lesenswert?

Hubert G. schrieb:
> Bei dem Konstrukt ist die Wahrscheinlichkeit sehr groß, das erstens der
> Taster nicht lange hält, zweitens der Kontroller undefiniert reagiert.

Auch ein Brown Out Reset ist eine definierte Reaktion.
Und mit der Schaltung vermutlich sogar reproduzierbar.
Bis der Taster weg/fest brennt.

Wenn, dann:
Internen Pullup verwenden  (spart einen Widerstand ein)
Kondensator kleiner, z.B. 100nF
Strombegrenzungswiderstand zwischen Taster und Kondensator.

Dann ist das eine recht stabile Hardwareentprellung.

von Mike1996 (Gast)


Lesenswert?

Ok, probiere ich aus.

Lothar M. schrieb:
> Warum ein Pulldown, wenn der uC schon einen Pullup hat?
> Mit dieser Beschaltung funktionert Entprellen nur mäßig und nur, wenn
> der µC Schmitttrigger-Eingänge hat.

Gilt das dann trotzdem ?

von Mike1996 (Gast)


Angehängte Dateien:

Lesenswert?

So ?

von Mike1996 (Gast)


Lesenswert?

Sry, falsch gezeichnet, der Kondensator parallel zum Schalter?

von Einer K. (Gast)


Lesenswert?

Mike1996 schrieb:
> Sry, falsch gezeichnet, der Kondensator parallel zum Schalter?
Zeichne nochmal richtig, dann kann man Ja oder Nein sagen.

von Mike1996 (Gast)


Angehängte Dateien:

Lesenswert?

So ?

von HildeK (Gast)


Lesenswert?

Peter D. schrieb:
> In Software macht man dazu einen gleitenden Mittelwert über z.B. 4
> Abtastungen. Das Abtastintervall wählt man größer als die Prellperiode,
> aber nicht so groß, daß der Nutzer eine Verzögerung merkt (typisch
> 2..50ms). 4 aufeinanderfolgende Einsen werden dann als 1 interpretiert,
> 4 aufeinanderfolgenden Nullen als 0. Alle anderen Muster bewirken keine
> Zustandsänderung. Fertig ist die Entprellung.

Das ist auch meine bevorzugte Variante wenn man
- keinen Timer/Interrupt verwenden will
- nur eine oder wenige Tasten hat

Ich hab es kürzlich mal so gelöst (mit den SBIT-Funktionen von PeDa) und 
dem Vergleich von 8 gleichen Zuständen. Taste ist Low-Aktiv und die 
Funktion liefert 1 bei gedrückter Taste. Es ist die Nachbildung eines 
Schieberegisters mit der Ausgangsverknüpfung UND und NOR, die ein RS-FF 
bedient.
1
  uint8_t get_key()  // Entprellung
2
  {
3
    static uint8_t shift;  // vorbesetzt vom letzten Tastendruck
4
    while(1)
5
    {
6
      if(KEY_in == 1) shift |= 1;  // Bit 0 setzen
7
      else shift &= ~1;         // Bit 0 löschen (&0xFE)
8
      _delay_ms (3); 
9
      if ( (shift == 0xFF) || (shift == 0) ) return (!shift & 0x01); // 8 mal hintereinander das selbe gelesen, Taste gedrückt bei LOW, get_key liefert dann '1'
10
      shift <<= 1; 
11
    }
12
  }

Mike1996 schrieb:
> So ?

Ja.

von Einer K. (Gast)


Lesenswert?

Mike1996 schrieb:
> So ?
Jawoll!
Genau so kann eine funktionierende Hardware Entprellung aussehen.


Aber eigentlich sind wir hier ja bei einer Software Entprellung.
Eine solche ist in den allermeisten Fällen vollkommen ausreichend, meist 
erheblich billiger und flexibler was die Zeiten angeht..

Die Hardwareentprellung beginnt erst Sinn zu machen, wenn man den 
Eingang per Interrupt auswerten muss. Und ohne das MUSS machen 
Interrupts an der Stelle keinen Sinn.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Mike1996 schrieb:
> Gilt das dann trotzdem ?
Ja, klar. Mit der ganzen RC-Bastelei wird es zwar ständig besser, aber 
den eigentlichen Trick mit dem Schwellwert bringt erst ein 
Schmitttrigger.

HildeK schrieb:
1
  uint8_t get_key()  // Entprellung
2
  {
3
    static uint8_t shift;  // vorbesetzt vom letzten Tastendruck
4
    while(1)
5
    {
Ich weiß nicht, mir gefällt dieses blockierende Programmierung nicht. 
Ich mache selbst einfachste Sachen in der Hauptschleife mit z.B. einem 
10ms-Flag in einem Zustandsautomaten und einem "Betätigungsdauerzähler":
- wenn die Taste nicht gedrückt ist, dann setze den Zähler zurück
- wenn die Taste gedrückt ist, dann zähle den Zähler hoch
- wenn der Zähler 5 (oder auch 10) erreicht, dann ist die Taste gedrückt
- nebenher Zähler sättigen (nicht dass ein Überlauf seltsame Dinge 
bewirkt)
Das sind je nach Programmierstil 2..3 drei unabhängige Abfragen, die 
sogar noch in beliebiger Reihenfolge kommen können:
1
  uint8_t z = 0;
2
3
  for (;;) {
4
    :
5
    if (flag_10ms) {
6
       :
7
       if(taste_gedrueckt) z++;
8
       else                z=0;
9
       
10
       if (z>=5) {
11
         z=5; // Zähler begrenzen
12
         // Taste entprellt und mindestens 50ms gedrückt
13
         // machwas...
14
       }
15
       :
16
    }
17
    :
18
  }

HildeK schrieb:
> Ich hab es kürzlich mal so gelöst
Weil bei einem Linksshift eine 0 von rechts hereingeschoben wird, ließen 
sich diese beiden Zeilen noch abkürzen:
1
      // original
2
      if(KEY_in == 1) shift |= 1;  // Bit 0 setzen
3
      else shift &= ~1;            // Bit 0 löschen (&0xFE)
4
5
      // kürzer
6
      if(KEY_in == 1) shift |= 1;  // Bit 0 setzen falls nötig. Default=0
7
8
      // noch kürzer
9
      shift |= KEY_in;

: Bearbeitet durch Moderator
von Einer K. (Gast)


Lesenswert?

Lothar M. schrieb:
> Ich mache selbst einfachste Sachen in der Hauptschleife mit z.B. einem
> 10ms-Flag in einem Zustandsautomaten und einem "Betätigungsdauerzähler":
In der Arduinowelt gibt es millis().
Einen weiteren Timer Interrupt für den Zweck etablieren ist nicht sehr 
sinnvoll.
Also muss man mit millis() zurande kommen.
Und ja, das Entprellen erfordert einen Zustandsautomaten. Und sei er 
noch so primitiv.

Lothar M. schrieb:
> Ich weiß nicht, mir gefällt dieses blockierende Programmierung nicht.
Mir auch nicht.
"blockierende Programmierung" ist wie ein Stock in den Speichen.

Lothar M. schrieb:
> Ja, klar. Mit der ganzen RC-Bastelei wird es zwar ständig besser, aber
> den eigentlichen Trick mit dem Schwellwert bringt erst ein
> Schmitttrigger.
Der hier behandelte AVR(hoffe ich doch mal) hat Schmitttriger Eingänge.

von HildeK (Gast)


Lesenswert?

Lothar M. schrieb:
> Ich weiß nicht, mir gefällt dieses blockierende Programmierung nicht.

Ich sagte ja auch: wenn ich keinen Timer verwenden will. In diesem Fall 
habe ich aus Stromspargründen Timer, ADC usw. im PRR abgeschaltet. Ich 
hatte keinen Arduino verwendet, wo der ggf. sowieso läuft.
In meiner Verwendung war ein 'Blockiern' überhaupt kein Thema, die 
meiste Zeit ist der Prozessor eh im Tiefschlaf ...

Lothar M. schrieb:
> Weil bei einem Linksshift eine 0 von rechts hereingeschoben wird
> .
> .
> // noch kürzer
>       shift |= KEY_in;

Danke, du hast ja recht - schau ich mir noch an! Ich bin nicht der 
Software-Profi, aber für solche Hinweise immer sehr dankbar ...

von HildeK (Gast)


Lesenswert?

Lothar M. schrieb:
> Weil bei einem Linksshift eine 0 von rechts hereingeschoben wird, ließen
> sich diese beiden Zeilen noch abkürzen:      // original
>       if(KEY_in == 1) shift |= 1;  // Bit 0 setzen
>       else shift &= ~1;            // Bit 0 löschen (&0xFE)
>
>       // kürzer
>       if(KEY_in == 1) shift |= 1;  // Bit 0 setzen falls nötig.Default=0
>
>       // noch kürzer
>       shift |= KEY_in;

Habs mir angeschaut. Geht so nicht.
Sie entprellt zwar den Übergang von KEY_in=0 auf 1, nicht aber die 
andere Richtung. Die geht nicht mal mehr, es kommt keine Null ...
Man könnte aber bei
1
 static uint8 shift;
das 'static' weglassen und dafür shift mit z.B. 0xAA vorbesetzten.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

HildeK schrieb:
> Die geht nicht mal mehr, es kommt keine Null ...
Dann nimmt KEY_in völlig unerwarteterweise auch andere Werte als 0 und 1 
an ;-)

HildeK schrieb:
> das 'static' weglassen und dafür shift mit z.B. 0xAA vorbesetzten.
Das wäre sowieso sinnvoll, denn mit dem static wird evtl. gar nichts 
entprellt, weil das static gespeicherte Abbild des Tasters mit der 
Umwelt (und dem realen Tasterzustand) gar nichts zu tun hat.
Oder andersrum: wenn shift vom letzten Aufruf von keypress() noch 0xff 
ist und wieder keypress aufgerufen wird, dann reicht theoretisch ein 
einziger high Impuls (oder eine weiterhin gedrückte Taste) zum 
Afragezeitpunkt um sofort wieder ein 0xff in shift zu erzeugen und die 
Routine ohne jegliche Entprellzeit sofort zu terminieren.

: Bearbeitet durch Moderator
von HildeK (Gast)


Lesenswert?

Lothar M. schrieb:
>> Die geht nicht mal mehr, es kommt keine Null ...
> Dann nimmt KEY_in völlig unerwarteterweise auch andere Werte als 0 und 1
> an ;-)

Nein, sicher nicht :-)
Das Problem war das links Schieben, das in meinem obigen Beispiel am 
Ende gemacht wurde. Es müsste so aussehen, dann passt die gewünschte 
Funktion und deine Vereinfachung:
1
  uint8_t get_key()  // Entprellung
2
  {
3
    static uint8_t shift;  // vorbesetzt vom letzten Tastendruck
4
    while(1)
5
    {
6
      shift <<= 1; 
7
      shift |=  KEY_in;  // Bit 0 setzen
8
      _delay_ms (3); 
9
      if ( (shift == 0xFF) || (shift == 0) ) return (!shift & 0x01); 
10
    }
11
 }

Lothar M. schrieb:
>> das 'static' weglassen und dafür shift mit z.B. 0xAA vorbesetzten.
> Das wäre sowieso sinnvoll, denn mit dem static wird evtl. gar nichts
> entprellt, weil das static gespeicherte Abbild des Tasters mit der
> Umwelt (und dem realen Tasterzustand) gar nichts zu tun hat.
> Oder andersrum: wenn shift vom letzten Aufruf von keypress() noch 0xff
> ist und wieder keypress aufgerufen wird, dann reicht theoretisch ein
> einziger high Impuls (oder eine weiterhin gedrückte Taste) zum
> Afragezeitpunkt um sofort wieder ein 0xff in shift zu erzeugen und die
> Routine ohne jegliche Entprellzeit sofort zu terminieren.

Doch, das 'static' passt schon. Es ist der Zustand, den die Taste beim 
letzten Aufruf hatte. Einzig: man könnte 'shift' mit 0xFF vorbesetzen, 
weil das der Zustand der ungedrückten Taste ist, was am 
wahrscheinlichsten beim Start des Programms ist.
Ist der Taster losgelassen, dann ist der letzte Zustand (Taster Low 
aktiv) von shift = 0xFF. Sollte die Routine wieder aufgerufen werden, 
ohne gedrückten Taster, dann beendet sie sofort (nach einem Delay), weil 
zu dem 0xFF - geschoben zu 0xFE - wieder eine 1 am LSB hinzugefügt 
wurde. Kein Problem.
Wurde die Taste gedrückt, dann werden, wie du sagtest, automatisch auf 
LSB-Seite Nullen eingeschoben, das müssen dann auch 8 Nullen 
nacheinander sein. Die Routine läuft so lange, bis shift 0x00 ist und 
gibt dann 'gedrückt' zurück - im besten Fall in 8 mal der Delayzeit.
Wird die Taste länger gedrückt oder länger losgelassen, dann kommt eben 
bei weiteren Aufrufen der Funktion fast sofort, mit nur einer Delayzeit, 
der aktuelle Zustand zurück.
Jede Störung oder Änderung, ob bei der losgelassenen oder gedrückten 
Taste, müsste dann schon 8 Delayzeiten anstehen.

Ich finde, die Lösung durchaus brauchbar, wenn die 'Blockierung' 
woanders keine Hemmnisse hervorruft.

von Stefan Mayerhofer (Gast)


Lesenswert?

Hallo Leute,

Stefan US hat mir diesen Code hier geschickt der softwaremäßig Taster 
entprellt.

unsigned long sperrzeit=0;

void loop()
{
    if (!digitalRead(2)) // Wenn die Taste nicht gedrückt ist ...
    {
        // Taste wurde losgelassen oder prellt

        // Messung der Sperrzeit erneut beginnen
        sperrzeit=millis();

        // LED aus
        digitalWrite(7,LOW);
    }
    else // ansonsten (also wenn die Taste gedrückt ist)...
    if (millis()-sperrzeit > 50) // Wenn die Sperrzeit überschritten 
wurde
    {
        // Taste wurde lange genug gedrückt
        // LED an
        digitalWrite(7,HIGH);
    }
}

Nun meine Frage, wieso funkt mein Programm nicht ?


 unsigned long Variable1;
 boolean Variable2=0,tastergedrückt=0;
 int AbfrageobPrellt=0,entprellzeit=50;

void loop()
{
   tastergerückt=digitalRead(Pin2);
   if(tastergedrückt)
{
    Variable1=millis();

}

if ((millis()-Variable1)>entprellzeit) //entprellzeit=50ms
 {
    //Nach 50ms nochmal die Abfrage

      if(tastergedrückt)
      {
      AnfrageobPrellt++;
      digitalWrite(Pin1,HIGH);
      }
 }

if(!tasterdegrückt)
{
  digitalWrite(Pin1,LOW);
}

Serial.println(AbfrageobPrellt);



Im Serial monitor wird per Tastendruck die Variable "AbfrageobPrellt" 
immer um ~30mal erhöht also prellts immer noch, oder ist der uC so 
schnell das er das loop 30mal durchläuft während ich kurz gedrückt habe 
?
Wo könnt ich die Variable sonst hinsetzten um zu prüfen obs prellt oder 
nicht ?

von Logiker (Gast)


Lesenswert?

Stefan Mayerhofer schrieb:
> Nun meine Frage, wieso funkt mein Programm nicht ?

Weil du kein Funkgerät angeschlossen hast.

von Stefan Mayerhofer (Gast)


Lesenswert?

Spar dir die Zeit für was sinnvolles.

von Stefan F. (Gast)


Lesenswert?

Der Timer soll zurückgesetzt werden, wenn der Taster NICHT gedrückt 
wurde (beachte das "!").
Danach hast du das "else" ausgelassen.

Danach hast du einen weiteren unnötigen Check "if (tastergedrückt)" 
eingebaut, das habe ich Dir nicht vorgeschlagen.

> AnfrageobPrellt++;

Was soll das werden?

von Stefan Mayerhofer (Gast)


Lesenswert?

Diese Variable soll mir im Serial monitor nur anzeigen ob der Taster 
prellt, es zeigt mir beim tastendruck 30 stk davon an.

Meine Überlegung nun:

1)Ich Frage den Taster ab
2)Taster gedrückt ? Wenn Ja dann soll die Zeit mal abgefragt werden mit 
millis().

3)Sind nun seit der Zeit wo das erste mal gedrückt wurde 50ms vergangen 
frage ich zur Sicherheit nochmal ab ob der Taster nun wirklich NOCH 
gedrückt ist.
 Das habe ich als eigenes if gemacht damit es auch nach 50ms erfüllt 
werden kann. Dh das Programm läuft weiter bis 50ms vergangen sind und 
springt dann in die if rein.

4)Wenn ja dann leuchtet die LED und die Variable "abfrageobprellt" soll 
hochgezählt werden um sie mir im Serial monitor anzuschauen.

5)Falls nicht gedrückt wird dann soll einfach die LED nicht leuchten.

Bitte erkläre mir wieso das so nicht passt und wieso die Zeit gemessen 
werden soll wenn der Taster NICHT gedrückt ist, die Zeit wird abgefragt 
wenn gedrückt wird danach läuft das Programm 50ms weiter und springt 
erst dann in die zweite if Abfrage hineine und die LED leuchtet. Ich 
raff nicht was daran falsch ist :(((

von Stefan F. (Gast)


Lesenswert?

Ichn habe Dir schon erklärt, warum dein Code nicht funktioniert. Deine 
if Abfragen folgen einer völlig anderen Logik, als mein Beispiel.

Wenn Du trotz Hinweis nicht verstehst, dass dein fehlendes 
Ausrufezeichen und ein fehlendes "else" die ganze Logik kaputt machen, 
dann kann ich Dir auch nicht weiter helfen.

Außer vielleicht mit dem Ratschlag, die Grundlagen der 
Programmiersprache zuerst mit einem PC Programm (ganz ohne 
Mikrocontroller) zu lernen. Und lerne auch, den Debugger zu benutzen, 
denn damit kannst du Schritt für Schritt zugucken, wie das Programm 
abläuft.

Lade Dir einfach mal Visual Studio runter, oder QT Creator und lerne 
damit.

von Stefan Mayerhofer (Gast)


Angehängte Dateien:

Lesenswert?

Ich schaff das nicht, hab vorhin sogar eine Schaltung wie im ANhang 
nachgebaut mit 10k bzw.1k und 100nF (Vcc 5V). Auch dies genau 0 
Besserung. Bin schon am Verzweifeln. Erfahrung habe ich im Dev-C++ 
gesammelt.
Habe einen Pull Up Widerstand.
Auch versucht mit Pull DOwn und auch mit Internen Pull Up und und und, 
bin nur mehr am probieren aber es funktioniert einfach nicht den Taster 
zu entprellen.

Habe ein ganz kleines Programm wo ich nur einen Taster abfrage, wenn der 
Taster gedrückt ist gebe ich am Serial Monitor "GEDRÜCKT" aus.

So, ich drücke einmal die Taste und es steht "GEDRÜCKT" ca. 40-50mal am 
Bildschirm. Keine Software und keine Hardware funktioniert bei mir.
Ich hätte schon so viele Ideen die ich weitermachen könnte, aber ich 
will Ohne dieses Problem zu lösen einfach nicht weitermachen weil ich 
dann ja nur herumpfusche.

Bitte gebt mir einen Lösungsvorschlag.

von Philipp K. (philipp_k59)


Lesenswert?

Arduino IDE->Beispiele->Digital->Debounce

ledState = !ledState; ersetzen mit Serial.println("taster gedrückt");

;)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Stefan Mayerhofer schrieb:
> Habe ein ganz kleines Programm wo ich nur einen Taster abfrage, wenn der
> Taster gedrückt ist gebe ich am Serial Monitor "GEDRÜCKT" aus.
> So, ich drücke einmal die Taste und es steht "GEDRÜCKT" ca. 40-50mal am
> Bildschirm.
Entprellen hat mit Flankenerkennung erst mal nichts zu tun. Wenn du da 
natürlich was ausgibst solange der Taster gedrückt ist, dann kommt da 
natürlich solange du den Taster drückst auch was heraus.
Wenn bei 1 Tastendruck beliebiger Länge nur 1x etwas ausgegeben werden 
soll, dann brauchst du zuerst eine Entprellung und danach eine 
Flankenerkennung.

Stefan Mayerhofer schrieb:
> oder ist der uC so schnell das er das loop 30mal durchläuft während ich
> kurz gedrückt habe ?
Ja, denk mal einfach, dass er auch wenn er langsam ist, in 1 Sekunde 
locker tausend Zeilen "schafft"...

Stefan Mayerhofer schrieb:
> jedoch will ich nicht blind was kopieren oder auswendig lernen sondern
> es selber schreiben und wirklich durchdenken.
Tu das. Es ist ein guter Ansatz.

: Bearbeitet durch Moderator
von Einer K. (Gast)


Lesenswert?

Stefan Mayerhofer schrieb:
> oder ist der uC so
> schnell das er das loop 30mal durchläuft während ich kurz gedrückt habe
> ?

Je nach dem, was zu tun ist, sind durchaus 100000 Loopdurchläufe/s, und 
auch mehr, zu erwarten.
Um nur 30 zu erwischen, musst du schon SEHR schnell wieder loslassen.

Dir wurde die Hardware Entprellung erklärt.
Dir wurde der Umgang mit millis() gezeigt.
Dir wurde Code vorgekaut.

Und dennoch:

Stefan Mayerhofer schrieb:
> Bitte gebt mir einen Lösungsvorschlag.
Eigentlich geht da nichts mehr.
Ich habe keine Antwort mehr für dich.

Außer vielleicht:
> Du musst dein Ändern leben!

Oder, wie kann ich dir helfen?

// ----

OK OK, eins fällt mir noch ein!
Die Nachtwächter Erklärung aus dem Arduino Forum.
Die  beschreibt wie man zeitgesteuerte endliche Automaten baut.
Ein Entpreller ist genau ein solcher Automat.
https://forum.arduino.cc/index.php?topic=423688.0

--

Aber das schöne daran ist, wenn du diesen Bereich gefressen hast, 
verstanden hast, dann hast du ein ganz wichtiges Kapitel gelernt.
Denn das Verfahren ist Grundlegend für nahezu alle deine weitere µC 
Programmierung!
Immer!
Zeitsteuerung, und Automaten.

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.