Petr schrieb:> Zuornung des Taster erfolgt damit:#define taster1 PORTA &= ~(1<<PINA1)> // PA1 ein> Das bringt zwar keine Fehlermeldung, funktioniert aber nicht.> Mit Zuordnung von LEDs mach ich es so ohne Probleme. Hab da wohl was> micht verstanden
Genau, LEDs hängen an Ausgängen des µC, während Taster an Eingängen
hängen. Es nützt also nichts, wenn du bei einem Taster irgendetwas auf
den Port zuweist ("PORTA &="...)
Petr schrieb:> Hab da wohl was micht verstanden
Ja.
Tastenzustände muss man einlesen und entprellen,
du machst eine Ausgabe an ein Port.
Auch dein zweiter Ansatz verwendet PORT statt PIN, und entprellt nicht.
Programmieren ist nicht dein Ding.
Petr schrieb:> _delay_ms(20); // Tasterentprellung
Das ist Rechenzeitverschwendung.
Du kommst da aber noch selber drauf, falls du in diesen 20ms noch was
anderes erledigen willst oder sogar musst. Denn wenn dein µC mit 8MHz
taktet, dann verschenkst du da immerhin 160000 (in Worten
einhundertsechzigtausend) Maschinenzyklen, in denen der Prozessor was
Sinnvolles machen könnte...
Lothar M. schrieb:>> _delay_ms(20); // Tasterentprellung> Das ist Rechenzeitverschwendung.
Das ist so eine Sache wie mit der heißen Herdplatte. Manche Erfahrung
muss der mensch selbst machen, um den Sinn hinter der Warnung zu
begreifen.
Ist ja auch nicht schlimm, Programme sind nicht in Stein gemeißelt.
Stefan ⛄ F. schrieb:> Lothar M. schrieb:>>> _delay_ms(20); // Tasterentprellung>> Das ist Rechenzeitverschwendung.>> Das ist so eine Sache wie mit der heißen Herdplatte. Manche Erfahrung> muss der mensch selbst machen, um den Sinn hinter der Warnung zu> begreifen.>> Ist ja auch nicht schlimm, Programme sind nicht in Stein gemeißelt.Lothar M. schrieb:> Petr schrieb:>> _delay_ms(20); // Tasterentprellung> Das ist Rechenzeitverschwendung.>> Du kommst da aber noch selber drauf, falls du in diesen 20ms noch was> anderes erledigen willst oder sogar musst. Denn wenn dein µC mit 8MHz> taktet, dann verschenkst du da immerhin 160000 (in Worten> einhundertsechzigtausend) Maschinenzyklen, in denen der Prozessor was> Sinnvolles machen könnte...
Ist es sinnvoll oder gar guter Stil? Nein!
Funktioniert es für diese eine Sache weil die MCU eh in 90% der Zeit was
anderes macht? Vermutlich!
Klar gibts bessere Möglichkeiten, sogar hier im Wiki gut dokumentiert.
Aber why not. Wenn ich q&d was brauche und mich die 20ms nicht stören,
so what.
Möchte nicht wissen wie viele Anfänger vor diesem Problem stehen, sich
die hier angebotenen Routinen zur Entprellung anschauen und erstmal
abschalten weil sie nix verstehen. Gerade durch Arduino und Co gibts so
viele die sich da ran trauen ohne jemals auch nur eine
Unterrichtseinheit "programmieren" im Leben gehabt zu haben...
Aber das ist Standard hier, das man nach a) fragt und direkt x) noch mit
aufgedrückt bekommt, mit sarkastischen Kommentaren (Herdplatte und
so...) ...
"ja das funktioniert so, ist aber schlecht weil, besser würde es gehen
wenn du es so machst" ... Stattdessen bekommt man sprichwörtlich das
Brett vor den Kopf geknallt.
Kratzt euch doch mal an der Nase und fragt euch ob euer eigenes
Auftreten hier nicht vielleicht einer der Gründe ist warum es hier zu
geht wie es hier eben zu geht...
Das mit den 20ms ist mir vollkommen klar, ist Zeitverschwendung. Das
Programm soll aber nur das können. Wenn ich mehr Zeit brauche kann ich
die Entprellung von Peter nehmen.
Brett vor den Kopf geknallt .... ?
Ich A. schrieb:> Möchte nicht wissen wie viele Anfänger vor diesem Problem stehen, sich> die hier angebotenen Routinen zur Entprellung anschauen und erstmal> abschalten weil sie nix verstehen. Gerade durch Arduino und Co gibts so> viele die sich da ran trauen ohne jemals auch nur eine> Unterrichtseinheit "programmieren" im Leben gehabt zu haben...
Immerhin sind Blockadefreie Varianten in den Arduino IDE Beispielen
untergebracht.
Über Effizienz und Schönheit kann man bekanntlich streiten, aber die
dort vorgestellten Prinzipien funktionieren und werden auch fleißig im
Arduino Universum eingesetzt.
https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelayhttps://www.arduino.cc/en/Tutorial/BuiltInExamples/Debounce
EAF schrieb:> Immerhin sind Blockadefreie Varianten in den Arduino IDE Beispielen> untergebracht... und werden auch fleißig im Arduino Universum eingesetzt.
Es sind halt nicht alle Arduidioten, wie c-hater-idiot sie gerne nennt.
Petr schrieb:> Das mit den 20ms ist mir vollkommen klar, ist Zeitverschwendung. Das> Programm soll aber nur das können.
Oft kommt später der Wunsch auf, das Programm zu erweitern.
Es ist auch nicht so, daß die 20ms sofort stören. Es können Sachen
ruckeln, Anzeigen flackern oder Drücke verloren gehen. Dann sucht man
sich nen Wolf, woran das liegen könnte.
Auch drücken Leute unterschiedlich lange, d.h. man will nur auf die
Flanke reagieren und keine versehentlichen Doppelaktionen.
Peter D. schrieb:> Oft kommt später der Wunsch auf, das Programm zu erweitern.
Hast du eine einfache (und kurze) Entprellung? Deine universelle
Entprellung ist super, aber vielleicht etwas zu gross für das Stück
Code.
Petr schrieb:> Hast du eine einfache (und kurze) Entprellung? Deine universelle> Entprellung ist super, aber vielleicht etwas zu gross für das Stück> Code.
Was ist daran zu groß? Die paar Zeilen und die paar Bytes sind
bedeutungslos.
Petr schrieb:> Hast du eine einfache (und kurze) Entprellung?
Wie sieht deine Programmstruktur aus?
Hast du eine Schritt-für-Schritt-Struktur, wo z.B. erst auf einen Taster
(z.B. Start-Taster) gewartet wird, danach dann eine Aktion ausgelöst und
auf den Abschluss dieser Aktion gewartet wird (z.B. Verfahren eines
Schrittmotors), und danach der nächste Schritt passiert (z.B. eine
Meldung angezeigt wird) und wenn der fertig ist, dann geht es wieder von
vorne los?
Oder hast du eine Hauptschleife, die ständig schnellstmöglich zyklisch
duchlaufen wird und arbeitest darin mit Zuständen und Automaten?
Petr schrieb:> Hast du eine einfache (und kurze) Entprellung?
Das ganze Programm sind nur ca. 40 Zeilen und nichts kompliziert. Es
soll einfach was machen wenn ich einen von 3 Taster drücke. Zeit ist
dabei vollkommen egal. Ist natürlich möglich das ich noch was anderes
draus mache, vielleicht mal...
Es ist ein Schritt für Schritt Programm, ganz einfach, nichts grosses.
Es ging mir nur um den Taster dabei und wie man ihn anders schreiben
kann.
Die Frage bleibt trotzdem, wer kennt eine ganz einfache Entprellung? Die
super Entprellung von Peter ist für diese Taster deutlich zu lang.
Petr schrieb:> Die Frage bleibt trotzdem, wer kennt eine ganz einfache Entprellung?
Wie kann man das in HW machen? Z.B. mit einem n-fach-Schieberegister und
anschließender NOR- und UND-Verknüpfung. Die NOR spricht an, wenn alle n
LOW sind, die UND, wenn n HIGH nacheinander eingelesen wurden. Für eine
HW-Lösung ist das ein ziemlicher Aufwand.
> Die super Entprellung von Peter ist für diese Taster deutlich zu lang.
Naja, von nichts kommt nichts.
Aber wie oben beschrieben, kann man das auch in SW auch machen - mit
deutlich weniger Aufwand.
Ein Timer (z.B. 2ms) gibt den Takt vor und bei jedem Timerinterrupt
liest du den Wert des Tasteneingangs und schiebst ihn in eine Variable
'shift'. Wenn alle n Bits von 'shift' Null bzw. Eins sind, dann änderst
du eine zweite Variable 'Taste_gedrückt' entsprechend auf Null oder
Eins. Fertig.
Wenn noch nicht alle Bits gleich sind (während der Prellzeit), dann
passiert nichts. Und es dauert mindestens n*2ms, bis eine Tastenänderung
akzeptiert wird; dafür ist das Prellen garantiert abgeklungen.
Ganz einfach zu programmieren ist es, wenn man n=8 nimmt (ein Byte),
dann muss man die Variable 'shift' nur jedes mal prüfen, ob sie 0x00
oder 0xFF ist.
Wie auch zu erkennen ist: man muss sowohl beim Drücken als auch beim
Loslassen der Taste entprellen.
Peter macht es im Prinzip nicht anders, nur sehr geschickt programmiert
und er kann gleichzeitig vier (oder acht?) Tastenpins einlesen und kann
noch unterscheiden zwischen lang und kurz gedrückt für eine
Doppelfunktion.
Auch wenn mein Vorschlag weniger effektiv ist, so macht er dir deutlich,
welches Prinzip dahinter steckt. Wenn du das verstanden hast, dann
kopiere einfach den Vorschlag von Peter, denke nicht weitere darüber
nach und nutze den Code immer wieder.
Für leere Flash-Bereiche in deinem µC gibt's kein Geld zurück ...
Peter D. schrieb:> Also ist Dein Flash am Anschlag oder wie?
Nein, es ist noch genügend frei. Mir erscheint es für einen kleinen Code
von vielleicht 20-40 Zeilen um 3 Taster abzufragen und 3 LEDs
einzuschalten eine Tasterentprellung zu nutzen die im Vergleich viel
komplizierter ist. Habe auch kürzere Sachen von dir gefunden. Muss mal
ansehen wie es zusammen passt.
Habe mir den Code von Petr gesucht. Meine diesen
https://www.mikrocontroller.net/articles/Entprellung
Das mit "Debounce-Makro von Peter Dannegger" gefällt mir sehr gut.
versuche mal rauszubekommen wie ich es nutzen kann. Eines ist mir aber
schon aufgefallen was ich nicht verstehe:
1
#define debounce( port, pin ) \
2
({ \
3
static uint8_t flag = 0; /* new variable on every macro usage */ \
4
uint8_t i = 0; \
5
\
6
if( flag ){ /* check for key release: */ \
7
for(;;){ /* loop ... */ \
8
if( !(port & 1<<pin) ){ /* ... until key pressed or ... */ \
9
i = 0; /* 0 = bounce */ \
10
break; \
11
} \
12
_delay_us( 98 ); /* * 256 = 25ms */ \
13
if( --i == 0 ){ /* ... until key >25ms released */ \
14
flag = 0; /* clear press flag */ \
15
i = 0; /* 0 = key release debounced */ \
16
break; \
17
} \
18
} \
19
}else{ /* else check for key press: */ \
20
for(;;){ /* loop ... */ \
21
if( (port & 1<<pin) ){ /* ... until key released or ... */ \
Welche Funktion haben ({ und }) am Anfang und Ende?
Haben die Zeichen \\\\ am Ende auch was mit dem Code zu tun oder dienen
sie einfach zur Abgrenzung?
Dann steht da noch #define debounce( port, pin ) gefolgt von diesen
Klammern ({ ... }). ????
Sorry da sehe ich nicht durch. Bitte um Aufklärung.
Lothar M. schrieb:> Petr schrieb:>> _delay_ms(20); // Tasterentprellung> Das ist Rechenzeitverschwendung.>> Du kommst da aber noch selber drauf, falls du in diesen 20ms noch was> anderes erledigen willst oder sogar musst.
Das ist ein an den Haaren herbei gezogenes Problem, was man nur in
wenigen Anwendungen hat.