Hi,
wenn ich einen Taster habe und beim betätigen eine Funktion ausführen
möchte habe ich (mir) zwei bekannte möglichkeiten. Zum einem kann ich
eine ISR aufrufen, die beim betätigen ausgeführt wird. Andersherum kann
ich aber auch den Taster immer wieder abfragen. Dabei habe ich gelernt,
dass wenn ich immer abfrage und der Taster betätigt ist, ich eine
gewisse zeit warten muss, da der Taster nicht sofort umspringt und somit
öfters betätigt wird. Ich frage z.B. ab, ob sich der status des Tasters
geändert hat, warte etwas und frage dann ab, ob der Status immer noch so
ist. Ist das bei einem Interrupt denn nicht genauso? Woher erkennt
diese, dass der Taster gedrückt wurde? wiso läuft diese dann nicht
zweimal durch?
Mark
Mark schrieb:> Woher erkennt> diese, dass der Taster gedrückt wurde? wiso läuft diese dann nicht> zweimal durch?
Wenn man von einem idealen Taster ohne Prellen ausgeht, könntest du ja
deinen Interrupt so konfigurieren, das er z.B. nur bei einer fallenden
Flanke auslöst, oder in der ISR schauen, ob der Pegel des Tasters jetzt
auch wirklich auf low ist, ansonsten wird nur verworfen.
Das Problem ist bei freilebenden Tastern natürlich das Prellen. Meistens
sind MC viel schneller als die Prellerei und dadurch wird die ISR
mehrfach ausgelöst.
Das ist einer der Gründe, warum man entweder in der ISR mehrfach auf
Plausibilität prüfen muss, was Zeit kostet (und ISR blocken im
Allgemeinen den MC komplett), oder per Hardware entprellen muss (RC
Kombination oder so was) oder eben doch mittels Timer den Taster
regelmässig pollen und dort Prellen eliminiert.
Mark schrieb:> Ist das bei einem Interrupt denn nicht genauso?
Ja.
Und deshalb nimmt man den Timerinterrupt, z.B. alle 10ms. Ist in z.B. 4
Aufrufen der Zustand gleich, übernimmt man ihn und wertet die Flanke
aus.
Das kostet nur unmerkbar CPU-Zeit, da nirgends gewartet werden muß.
Wenn dein Programm aus einer Endlosschleife besteht, die den Zustand des
Tasters pollt, dann kannst du beim Status "gedrückt" einfach 100ms
warten, bevor du ihn erneut abfragst. Eventuell ergibt sich das bereits
von selbst, z.B. weil dann etwas auf einem Display angezeigt wird und
die Kommunikation zum Display bereits so lange dauert.
Ich wollte noch auf die anderen Eingehen:
> Ist das bei einem Interrupt denn nicht genauso?
Im Prinzip schon. Jetzt kommt es drauf an, welchen Interrupt du meinst.
Wenn der Taster selbst einen Interrupt auslöst, und die Interruptroutine
kurz ist (zum Beispiel <1ms), dann kann ein einzelner Tastendruck
durchaus mehrere Interrupts auslösen.
Aber wenn die Interruptroutine selbst lange Zeit in Anspruch nimmt (z.B.
100ms) dann ist das prellen der Kontakte längst vorbei, bevor der
nächste Interrupt möglich wäre.
Du kannst den taster auch regelmäßig in einem Timner-Interrupt abfragen.
Wenn dessen Intervall kürzer ist, als die Prellzeit, dann kann ein
Tastendruck unerwünscht mehrmals erfasst werden. Wenn der
Timer-Interrupt jedoch nur alle 100ms aufgerufen wird, dann merkt er das
prellen gar nicht, weil das nicht so lange stattfindet.
> Woher erkennt diese, dass der Taster gedrückt wurde?
Am Pegelwechsel eine Eingangs (blöde Frage, oder ich verstehe die Frage
nicht so, wie sie gemeint war).
> Wieso läuft diese dann nicht zweimal durch?
Vermutlich, weil deine ISR länger dauert, als das Prellen des Tasters.
Stefan U. schrieb:> Eventuell ergibt sich das bereits> von selbst, z.B. weil dann etwas auf einem Display angezeigt wird und> die Kommunikation zum Display bereits so lange dauert.
Und mit sowas fällt der Anfänger regelmäßig auf die Nase, wenn er später
das Programm optimiert und nichts mehr stabil läuft.
Mindestzeiten erzeugt man mit Timern, denn dazu sind sie ja da (wer
hätte das gedacht).
Stefan U. schrieb:> while (1)> {> if (TASTER_GEDRUECKT)> {> zeige_etwas_auf_dem_display_an();> // _delay_ms(100);> }> }
ja, so meinte ich das ja auch. Aber es war mir nicht bewusst, dass ich
so etwas in der ISR machen kann, da diese ja möglichst kurz sein sollte
und eigentlich kein delay oder so da hineingehört.
Bisher waren auch alle beispiel-codes für eine ISR ohne eine solche
überprüfung.
Danke euch
Mark schrieb:> Aber es war mir nicht bewusst, dass ich> so etwas in der ISR machen kann, da diese ja möglichst kurz sein sollte> und eigentlich kein delay oder so da hineingehört.> Bisher waren auch alle beispiel-codes für eine ISR ohne eine solche> überprüfung.
"So etwas" macht man ja auch auf keine Fall in einer ISR.
Wenn du Beispiele für einen Flankengetriggerten IR meinst, dann MUSS das
Signal auf jeden Fall vorher entsprechend gefiltert sein (RC-Tiefpass)
> Aber es war mir nicht bewusst, dass ich> so etwas in der ISR machen kann, da diese> ja möglichst kurz sein sollte
Korrekt. Warteschleifen haben in Interrupt-Routinen normalerweise nicht
zu suchen.
Hast du den Anfang meiner Antwort überlesen?
> Wenn dein Programm aus einer Endlosschleife besteht,> die den Zustand des Tasters pollt ....
Für Interruptgesteuerte Sachen schlage ich sowas vor:
Zum einen hast du eine Timer-Interrupt, der einen Counter regelmäßig um
1 erhöht. Das müsste Dir von Windows oder Linux bekannt vorkommen. Dort
gibt es den "Systemtimer", der im 1ms Takt hochzählt. Diesen zentralen
Zähler benutzt du, um die Zeitpunkte von Ereignissen zu ermitteln und um
Zeitspannen zu messen.
Zum Anderen hast du eine Interruptroutine, die vom Taster ausgelöst
wird. Bei jedem Impuls prüfst du, wieviel Zeit seit dem vorherigen
Impuls verstrichen ist. Wenn das weniger als 100ms waren, ignorierst du
ihn.
> Wenn du Beispiele für einen Flankengetriggerten IR meinst, dann> MUSS das Signal auf jeden Fall vorher entsprechend gefiltert> sein (RC-Tiefpass)
Jedesmal wenn ich das vorschlage, werde ich verbal gesteinigt.
Entprellen mit Kondensator ist heutzutage anscheinend uncool.
Stefan U. schrieb:> Entprellen mit Kondensator ist heutzutage anscheinend uncool.
Grade für Einzelstücke kann man das schon mal machen finde ich. In
Großserie natürlich ist so was Käse, da wird jedes vermeidbare Bauteil
ganz schön teuer
Mark schrieb:> Aber es war mir nicht bewusst, dass ich> so etwas in der ISR machen kann
'machen' kannst du alles.
Du bist schliesslich der Programmierer und als solcher bist du auf
deinem µC einem Gott gleichgestellt. Der µC kann sich nicht wehren wenn
du so etwas tust.
Die Frage ist nicht, ob du das machen kannst, die Frage ist "wie schlau
ist das?"
> da diese ja möglichst kurz sein sollte> und eigentlich kein delay oder so da hineingehört.
Ganz genau.
Denn genau das wollen wir ja nicht haben, dass ein µC seine Zeit damit
verplempert, dass er sinnlos Däumchen dreht.
Als Faustregel kannst du dir merken:
Wenn in deiner Projektbeschreibung irgendwo das Wörtchen 'Zeit'
auftaucht, dann ist das in 99% aller Fälle ein Hinweis auf den Einsatz
eines Timers. Und da praktisch in jedem Programm es irgendeine Form von
Zeitsteuerung gibt (und sei es nur eine blinkende LED), taucht als Folge
davon auch in fast jedem Programm ein Timer auf. Und der kann dann auch
noch die Tasten nebenbei mit behandeln.
Stefan U. schrieb:> Zum Anderen hast du eine Interruptroutine, die vom Taster ausgelöst> wird. Bei jedem Impuls prüfst du, wieviel Zeit seit dem vorherigen> Impuls verstrichen ist. Wenn das weniger als 100ms waren, ignorierst du> ihn.
Das ist ja dann wohl ein bißchen des Guten zu viel!
Aber bei dem Wetter kann es einem die Gedanken schon verwirren.
Stefan U. schrieb:> Entprellen mit Kondensator ist heutzutage anscheinend uncool.
Das nun wiederum garnicht. Es hat den Vorteil, daß das auslösende
Schaltsignal schneller erkannt und verarbeitet werden kann. Bei einem
Taster für eine Rentner-Klingel, reicht eine Reaktionszeit von 1
Sekunde. Beim Reedschalter an der Fahrradspeiche muß deutlich schneller
reagiert werden, da der Impuls nicht lange vorhanden ist aber dennoch
Prellen aufweisen kann.
Zurück im Sommerloch!
Jan H. schrieb:> In> Großserie natürlich ist so was Käse, da wird jedes vermeidbare Bauteil> ganz schön teuer
Und da haber wir auch wieder einen Vertreter der Großindustrie, der nur
in Million Stückzahl denkt. Lächerlich!
Mark schrieb:> Stefan U. schrieb:>> while (1)>> {>> if (TASTER_GEDRUECKT)>> {>> zeige_etwas_auf_dem_display_an();>> // _delay_ms(100);>> }>> }>>> ja, so meinte ich das ja auch. Aber es war mir nicht bewusst, dass ich> so etwas in der ISR machen kann, da diese ja möglichst kurz sein sollte> und eigentlich kein delay oder so da hineingehört.
Richtig. Das macht man in einer ISR auf keinen Fall so. Und auch
außerhalb einer ISR macht man das so nach Möglichkeit nicht.
Korrekt macht man das mit einem Timer-Interrupt. In der Timer-ISR fragt
man den Zustand des Tasters ab und vergleicht mit dem Zustand der
letzten N Abfragen (= der letzten N Aufrufe der ISR). Im einfachsten
Fall ist N=1, dann muß sich die ISR nur den Zustand beim letzten Aufruf
merken (in einer static Variable). Und wenn der Taster dann alle N Mal
den gleichen Zustand hatte, dann kann man auch sicher sein, daß er
aufgehört hat zu prellen.
Und wenn dann die Aktion, die der Taster auslösen soll, nur wenig
CPU-Zeit braucht (z.B. einen Pin auf 1 setzen um eine LED anzuschalten)
dann kann man das direkt in der ISR tun. Wenn es hingegen etwas ist, was
längere Zeit in Anspruch nimmt (z.B. eine Textnachricht über den
seriellen Port senden) dann sollte die ISR nur eine Flag-Variable
setzen, die dann im Hauptprogramm geprüft wird. Und die Aktion sollte im
Hauptprogramm ablaufen.
Für Bastler ist das egal.
Blöd wirds, wenn
- das Gerät öfters gebaut wird
- wenn mehrere Taster angeschlossen sind
Jedesmal werden R und C gebraucht, gekauft, gelötet, getestet
Tasten-Software schreib man einmal und gut. Oder kopiert sie irgendwo
raus.
uncool schrieb:> Für Bastler ist das egal.>> Blöd wirds, wenn> - das Gerät öfters gebaut wird> - wenn mehrere Taster angeschlossen sind
blöd wirds auch, wenn der Hardware Entwickler nicht mitgedacht hat und
das RC-Glied so eingebaut hat, dass über kurz oder lang die
Tastenkontakte abbrennen, bzw das Netzteil aussteigt.
Siehe zb das unsägliche Pollin-Board.
Das schöne an einer SW-Entprellung ist auch, dass ich die SW auch
nachträglich noch leicht an die realen Gegebenheiten (Zeiten) anpassen
kann. Womit dann auch Reed Schalter an Fahrradspeichen wieder in
Reichweite kommen :-)
Eine SW Lösung erlaubt mir auch Zusatzfunktionalität wie zb die
Unterscheidung zwischen langem und kurzen Tastendruck bzw. ein
Autorepeat (was zb bei Zahleneingaben mittels 'Up' und 'Down' recht
praktisch ist)
Stefan U. schrieb:> Zum Anderen hast du eine Interruptroutine, die vom Taster ausgelöst> wird. Bei jedem Impuls prüfst du, wieviel Zeit seit dem vorherigen> Impuls verstrichen ist. Wenn das weniger als 100ms waren, ignorierst du> ihn.
Oder 100ms lang ignorieren, statt zu prüfen (Interrupt sperren, Flag
löschen, wieder freigeben)
Stefan U. schrieb:> Entprellen mit Kondensator ist heutzutage anscheinend uncool.
Es sind eben 3 Bauteile mehr (je Gerät und je Taster), die man durch
einige Zeilen Code problemlos ersetzen kann.
Und Code hat den Charme, man muß ihn nicht jedesmal einlöten, sondern
kann ihn nach dem Entwickeln einfach in weitere Projekte includieren.
Stefan U. schrieb:> Entprellen mit Kondensator ist heutzutage anscheinend uncool.
Was mich an diesen "Kondensatorentprellungen" stört, ist, dass man
allein mit einem Kondensator allein schon prinzipiell nicht entprellen
kann.
Man kann nur Störungen filtern und auf einen Schmitttriggereffekt mit
ein wenig Hysterese am µC-Eingang hoffen...
Eine richtige Entprellung ist für mich ein Zeitglied, das nach jeder
Prellflanke zurückgesetzt wird, und erst nach Ablauf der "Gesamtzeit"
einen stabilen Zustand am Pin signalisiert.
m.n. schrieb:> Jan H. schrieb:>> In>> Großserie natürlich ist so was Käse, da wird jedes vermeidbare Bauteil>> ganz schön teuer>> Und da haber wir auch wieder einen Vertreter der Großindustrie, der nur> in Million Stückzahl denkt. Lächerlich!
Wenn du mich zitierst, dann bitte richtig!
Jan H. schrieb:> Grade für Einzelstücke kann man das schon mal machen finde ich.
Also so viel zu “nur in Millionen Stückzahl“.
Schön, dass Beiträge vor dem meckern noch komplett gelesen werden.
Lothar M. schrieb:> Man kann nur Störungen filtern und auf einen Schmitttriggereffekt mit> ein wenig Hysterese am µC-Eingang hoffen...
Alle Pins an uCs die ich kenne und die eine Flankeninterrupt-Funktion
haben können, haben dann auch Schmitttriggercharakteristik.
Jan H. schrieb:> Schön, dass Beiträge vor dem meckern noch komplett gelesen werden.
Ich habe Deinen Text volständig gelesen und auch den Tenor:
"Ja, ABER ..."
Hättest Du die Reihenfolge umgedreht, hätte ich ja nichts gesagt. Wenn
Du viele Bauteile sparen willst, dann lasse fast alle
Abblockondensatoren weg. Das bringt richtig Kohle.
Gerne würde ich Dir 1000 Rs schenken (0805), aber das Porto wäre genauso
teuer wie die Widerstände.
Lothar M. schrieb:> Was mich an diesen "Kondensatorentprellungen" stört, ist, dass man> allein mit einem Kondensator allein schon prinzipiell nicht entprellen> kann.> Man kann nur Störungen filtern und auf einen Schmitttriggereffekt mit> ein wenig Hysterese am µC-Eingang hoffen...
Ohne Widerstand geht doch garnichts. Oder wie soll das Signal wieder
seinen passiven Pegel erreichen?
Lothar M. schrieb:> Eine richtige Entprellung ist für mich ein Zeitglied, das nach jeder> Prellflanke zurückgesetzt wird, und erst nach Ablauf der "Gesamtzeit"> einen stabilen Zustand am Pin signalisiert.
Man kann es aber auch anders herum machen, indem man die erste erkannte
Flanke hinter dem RC-Glied verwendet und den Kondensator voll auf den
neuen Pegel läd. Das geht schnell und sorgt für stabile Pegel, die nicht
um die Hysterese 'herumflattern'.
m.n. schrieb:> Ich habe Deinen Text volständig gelesen und auch den Tenor: "Ja, ABER> ..."
Dann passt ja alles. Ich hatte das mit der Großserie nur erwähnt, weil
sonst absolut sicher einer kommt, der genau deshalb einen Aufstand
macht. Der Fluch der schriftlichen Kommunikation ist halt, dass immer
irgendwer eine Betonung reininterpretiert, die nicht da ist. Soll
natürlich kein Vorwurf sein.
Peter D. schrieb:> Ist in z.B. 4> Aufrufen der Zustand gleich, übernimmt man ihn und wertet die Flanke> aus.
Du hast ne ausgesprochen seltsame Herangehensweise. Ich nehme hingegen
die allererste Gelegenheit, den "gedrückt"-Zustand als solchen zu
erkennen. Hinterher ist dann angesagt, solange alles zu ignorieren, bis
der Taster eine gewisse Zeit am Stück als ungedrückt erkannt wird -
oder bis die voreingestelle Repetierzeit überschritten ist. Deine Art
der Tastenabfrage macht das Ganze eher ein bissel zäh für den Benutzer,
weil die Reaktion zu spät kommt.
W.S.
W.S. schrieb:> Du hast ne ausgesprochen seltsame Herangehensweise.
Nö, eine praktische.
Damit wird nicht nur entprellt, sondern auch Störungen wirksam
unterdrücket (Handy, Staubsauger usw. in der Nähe, elektrostatisch
aufgeladene Kleidung, Stuhl, Teppich).
Außerdem spart es Code und CPU-Zeit (einfaches Entprellen eines ganzen
Ports parallel).
W.S. schrieb:> Deine Art> der Tastenabfrage macht das Ganze eher ein bissel zäh für den Benutzer,> weil die Reaktion zu spät kommt.
Du scherzt, 40ms merkt keiner, da ist jede GUI bei weitem träger.
Aber wenn Du so große Angst hast, kannst Du auch mit 1ms Timer arbeiten,
die 5..50ms sind nur meine praktische Empfehlung.
W.S. schrieb:> Du hast ne ausgesprochen seltsame Herangehensweise.
Das finde ich auch nicht, denn das hat sich bei mir auch bewährt. Ich
stelle einen Timer so ein, daß ich alle 1ms einen Interrupt ausgelöst
kriege und lasse mir in dessen Routine ggf. noch mehrere Hilfsvariablen
hochzählen, um unetrschiedliche Zeiten zu erzeugen, die aber alle starr
gekoppelt sind. Da kann sich nichts gegenseitig beharken.
Nun entprelle ich Taster auf die von Peter genannte Weise, kann dann
z.B. von der nächsten Hilfsvariable gesteuert eien AD-Wandler Kanal
abfragen usw.
Damit kriege ich schön Ordnung rein und es läuft, wie ein Länderspiel.
MfG Paul
W.S. schrieb:> Deine Art> der Tastenabfrage macht das Ganze eher ein bissel zäh für den Benutzer,> weil die Reaktion zu spät kommt.
Was hast du denn für einen Benutzer? Superman?
Kein normaler Mensch kann eine Reaktions-Verzögerung von 2 bis 3
Hunderstel Sekunden aktiv fühlen oder feststellen.
Stefan U. schrieb:>> Wenn du Beispiele für einen Flankengetriggerten IR meinst, dann>> MUSS das Signal auf jeden Fall vorher entsprechend gefiltert>> sein (RC-Tiefpass)>> Jedesmal wenn ich das vorschlage, werde ich verbal gesteinigt.>> Entprellen mit Kondensator ist heutzutage anscheinend uncool.
Nein es gibt hier offenbar eine Entprel-Mafia. Der Boss ist Herr
Dannegger (der offensichtlich einen Entprellfetisch oder eine
Inselbegabung in dem Bereich hat). Der wird von einer Horde Moderatoren
so was von vergöttert, -warum auch immer- die sich auf jeden Stürzen der
es wagt das Entprellen auf irgendeine andere Art zu lösen versucht als
durch Danneggers Code. Ist ja auch gemein. Immerhin hat er sich so viel
Mühe gegeben.
Jeder darf es auch andrs machen, aber dann bitte nicht wundern, daß die
Flanken-ISR nicht immer funktioniert. Anders kann ich mir nicht
erklären, warum dieses vor Jahren gelöste Problem min. 1-mal pro Woche
durch's Forum getrieben wird. Jedenfalls nicht von der Mafia dies kann.
Bastler schrieb:> Jeder darf es auch andrs machen, aber dann bitte nicht wundern, daß die> Flanken-ISR nicht immer funktioniert.
Wenn man es richtig macht funktionirt es doch auf beide Arten ...
Karl H. schrieb:> Was hast du denn für einen Benutzer? Superman?
Nee. Eher das komplette Gegenteil. Manche hacken auf die Tasten (so wie
mechanische Schreibmaschine: auf den Impuls kommt's denen an) und andere
sind derart langsam, daß ich die erste Repetierzeit auf etwa 1.5
Sekunden hochleiern mußte. Aber bei der "Draufhack"-Sorte ist eine Zeit
von 40 ms bis zum Erkennen einer gedrückten Taste zu viel. VIEL zu
viel. Die würden in solchen Fällen ein halbes dutzend mal draufhacken
und eben nicht ihren Finger draufHALTEN.
Inzwischen wandelt sich das ein bissel, weil mehr Touchscreens in
Verwendung kommen und die kapazitiven Touchs alle ein bissel zäh sind.
Naja, und Peters Einlassung wegen etwaiger Störungen kann ich nicht
vestehen. Ein lumpiger 22nF am Eingang erledigt sowas zu 100%. Jaja
sowas kostet selbst in der Serie sogut wie nix.
W.S.
HannisBalls schrieb:> Nein es gibt hier offenbar eine Entprel-Mafia.
Schön ruhig..
Hier geht es immer wieder um die außerordentliche Dämlichkeit, die der
diverse Nachwuchs an den Tag legt, wenn es um solche trivialen Dinge wie
das sinnvolle Entprellen von Tasten und die Abfrage von Drehgebern und
der sinnvollen Weiterverarbeitung der Abfrageergebnisse in
Mikrocontrollern geht.
Egal, wieviele Fraktionen (Poller,Interrupter oder sonstwas noch) sich
in dieser Angelegenheit tummeln - es ist immer wieder das Ärgernis mit
der nachwachsenden DUMMHEIT. Ich meine ausdrücklich nicht
"Unwissenheit", denn die kann man durch eigenes Nachdenken beseitigen.
Ob man es nun als gut oder pädagogisch eher bedenklich ansieht, wenn
Leute hier fertige Codeschnipsel zum Tastenentprellen posten, die dann
von solchen Dummköpfen ohne jegliche eigene Reflexion (!!!) benutzt
werden - wobei es dann oftmals hapert, weil jegliche Anpassung fehlt und
folgerichtig ein weiterer Beitrag in diesem Forum auftaucht "He..das
geht ja garnicht bei mir, helft mir mal gefälligst!" - das sei mal alles
dahingestellt.
W.S.