Guten Abend zusammen,
ich möchte 4 Schalterzustände einlesen. Die Schalter hängen an meinem
Mega8 an Port D und zwar PD0...PD3 und schalten Masse an den Port.
Schalter offen liegen am Port 5V an (interner Pullup).
Mich interessiert nicht der akute Zeitpunkt, wann er gedrückt wurde oder
nicht. Mich interessiert eigentlich nur, ob er gedrückt ist, auch wenn
das "Signal gedrückt" 1 Sekunde später ankommt. Es handelt sich dabei
nicht um einen Taster, sondern einen Schalter, der entweder Masse
durchschaltet oder nicht (dann +5V, interne Pullups aktiviert).
Im Programm möchte ich dann abfragen, welche Ports von PD0 bis PD3 auf
Masse liegen und welche nicht.
Wie machte ich das am besten?
Danke.
Daniel
Das kommt drauf an wie dein Restprogramm auf die Taster reagiert. Wenn
es Konfigschalter sind, die beim booten einmalig ausgelesen werden,
brauchst du keine Entprellung. Wenn sie während der Laufzeit ständig
abgefragt werden, brauchst du die Entprellung nur dann, wenn du die
Taster in "Echtzeit" abfrägst, also zb. in einem Timerinterrupt der alle
10ms kommt. Wenn du sie nur alle 200ms oder noch langsamer abfrägst,
kannst du die Werte direkt übernehmen. Dann muss der Taster allerdings
auch mindestens für diese Zeit gedrückt sein, denn sonst kann es sein
dass das Programm die Betätigung verpasst.
Hallo,
es ist in der Tat so gedacht, dass die Konfiguration beim Booten
abgefragt wird. Dies soll aber auch zur Echtzeit/Programmlaufzeit
verändert werden können. Das Programm muss aber das nicht direkt
erkennen, da es nicht zeitkritisch ist. Es genügt, wenn das Programm das
erst eine Sekunde später erkennen würde.
Du kannst die Schalter einfach auslesen. Das Entprellen muss man nur
machen wenn man auf das Drücken des Tasters reagieren will, aber nicht
mehrfach, wie es das Prellen auslösen würde.
Hi
Sorry, Leute, das ich da widerspreche... einen mechanischen Schalter, ob
Taster, Schützkontakt oder sonstwas ist immer zu entprellen. Es macht
keinen Sinn, sich darauf zu verlassen, das ein Signal "steht", wenn man
es für die Bearbeitung abfragt. Es sei denn, der Controller arbeitet
noch mechanisch, dann brauchts das nich.
gruß oldmax
Daniel schrieb:> Im Programm möchte ich dann abfragen, welche Ports von PD0 bis PD3 auf> Masse liegen und welche nicht.
...wenn dein programm nicht nur auf das einschalten reagieren soll,
sondern
das "wiederausschalten" auswerten soll,so musst du entprellen, es sei
denn dein Programm "verbrät" bis zur nächsten abfrage genügend zeit,
damit der schaltkontakt zur ruhe kommt.
selbst da ist aber nicht garantiert,ob nicht gerade wiedeholt
eingeschalten wurde (wütender schaltgnom) und er sich in der prellung
befindet und du gerade low einliest,obwohl er high sein sollte....
eine bewertung durch mehrfaches einlesen sollte als mindestabfrage drinn
sein und ist doch nur ein kleiner vers ;-)
p.s.
...sollte es sich um eine möglichkeit zur einstellung einer
konfiguration mittels dip-schalter handeln, so braucht man warscheinlich
keine entprelleng, diese werden ja bewusst und auch nur statisch
benutzt, da trauen sich die schaltgnome nicht ran :)
Hier noch eine Meinung zum entprellen:
Wenn der Schalter beim Einschalten als ---Aus - An - Aus - An--- und
beim Ausschalten andersherum gelesen werden darf, braucht man nicht zu
entprellen.
Daniel schrieb:> es ist in der Tat so gedacht, dass die Konfiguration beim Booten> abgefragt wird. Dies soll aber auch zur Echtzeit/Programmlaufzeit> verändert werden können. Das Programm muss aber das nicht direkt> erkennen, da es nicht zeitkritisch ist. Es genügt, wenn das Programm das> erst eine Sekunde später erkennen würde.
Es geht ja nicht um die Erkennungsgeschwindigkeit, sondern darum, ob es
was ausmacht, wenn der Anschein eines mehrfachen hin- und herschalten
innerhalb von ein paar Millisekunden entsteht, das in Wirklichkeit
eigentlich gar nicht stattgefunden hat. Wenn du den Schalter nur einmal
pro Sekunde abfragst, hast du quasi auch schon eine Art Entprellung
gemacht.
oldmax schrieb:> Hi> Sorry, Leute, das ich da widerspreche... einen mechanischen Schalter, ob> Taster, Schützkontakt oder sonstwas ist immer zu entprellen.
Nein. Es ist vom Anwendungsfall abhängig. Eine eigentlich unnötige
Entprellung schadet aber in der Regel auch nicht.
> Es macht keinen Sinn, sich darauf zu verlassen, das ein Signal "steht",> wenn man es für die Bearbeitung abfragt.
In manchen Fällen ist es aber egal, ob das Signal steht.
Denke mal an einen PAUSE-Taster bei einem mp3-Player. Ob ich die Taste
einmal oder dreimal kurz hintereinander drücke, ist völlig egal. Das
Ergebnis ist das selbe.
Oder auch ein Schalter bei einem Lauflicht, der die Richtung umschaltet.
Ob nun während des Umschaltens innerhalb weniger Millisekunden die
Richtung sich noch ein paarmal ändert, ist egal. Man sieht es nicht mal,
weil das Lauflicht zwischendurch gar keine Zeit hat, weiterzulaufen.
Ok, dann werde ich das zur Sicherheit entprellen.
Könnte mich noch bitte jemand Unterstützen, wie ich die Entprellung nach
Peter Danegger mit Timer-Verfahren auf die 4 Ports bekommen, also wie
ich in get_key_press() alle 4 Ports Abfrage ob sich etwas geändert hat
oder wie macht man das am Besten?
http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29
oldmax schrieb:> Sorry, Leute, das ich da widerspreche... einen mechanischen Schalter, ob> Taster, Schützkontakt oder sonstwas ist immer zu entprellen.
Auch ich muss da klar widersprechen. Nur wenn ein Taster/Schalter einen
Schritt auslöst, der nicht einfach wieder rückgängig gemacht werden
kann, muss er entprellt werden!
Und gerade Konfigurationsschalter sind unkritisch, denn wenn da mal kurz
ein falsche Konfiguration erkannt wird, dann wird das beim nächsten
Zyklus korrigiert, weil da dann die richtige Konfiguration erkannt wird.
Sonst dürfte man niemals mit einem Lichtschalter direkt ohne Entprellung
ein Licht einschalten...
Daniel schrieb:> Müsste ich die Funktion für alle 4 Schalter so aufrufen:if (get_key_press ( (
1<<PD0 ) |( 1<<PD1 ) |( 1<<PD2 ) |( 1<<PD3 ) ))
>> Und wenn sich dann eine Taste ändern, bekomme ich "WAHR" zurück?
Das wissen wir ja nicht, da uns die Funktion 'get_key_press' unbekannt
ist.
Übrigens packe ich Definitionen von Ports und Schalterleitungen gerne in
eine include Datei, z.B.
Matthias Sch. schrieb:> Das wissen wir ja nicht, da uns die Funktion 'get_key_press' unbekannt> ist.
Diese Funktion ist aus dem Tutorial (obiger Link) Entprellung nach Peter
Danegger.
Ich habe aber die Befürchtung, dass die Funktion nur das Drücken
erkennt, nicht aber das Loslassen, d.h. wenn ein Schalter wieder
rückgesetzt wird und keine Masse mehr durchschaltet, bekomme ich das
Ergeignis nicht mit, oder?
Daniel schrieb:> get_key_press()> Ich habe aber die Befürchtung, dass die Funktion nur das Drücken erkennt
Wie heißt die Funktion nochmal?
Was bedeutet "key press" auf deutsch?
Was bedeutet "taste loslassen" auf englisch?
Mit "key release" findet man dann den
Beitrag "Re: Universelle Tastenabfrage"
Hi
Rrolf Magnus schrieb:
>Denke mal an einen PAUSE-Taster bei einem mp3-Player. Ob ich die Taste>einmal oder dreimal kurz hintereinander drücke, ist völlig egal. Das>Ergebnis ist das selbe.
Da steckt mit sicherheit eine Flankenerkennung dahinter und das hat
nichts mit "Entprellen" zu tun. Da möchte ich auch fast drauf wetten,
das entprellt ist, bevor das Signal ausgewertet wird.
Lothar Miller:
>Sonst dürfte man niemals mit einem Lichtschalter direkt ohne Entprellung>ein Licht einschalten...
Seit wann ist eine Lampe ein µC...
Ich schrieb:
>Es sei denn, der Controller arbeitet>noch mechanisch, dann brauchts das nich.
Es ist mir ehrlich gesagt, völlig wurscht, ob entprellt wird oder nicht,
doch irgendwann kommt garantiert die Frage: "Warum führt ein Ändern von
Konfigurationssschaltern zu unbeabsichtigten Funktionen....."
Daher, wer es richtig macht, entprellt mechanische Schaltkontakte, um
eben ein Fehlverhalten seiner Erfindung möglichst zu verhindern.
Mal ein kleines Beispiel:
Schaltung aufgebaut und funktioniert. Nach einiger Zeit will irgend so
ein neugieriger Mensch wissen, wie oft an den Konfigurationsschaltern
gefummelt wird, also zählt man die Schaltvorgänge.... und staunt nicht
schlecht über das Ergebnis.
Was kostet eine Entprellung ? Bestimmt weniger wie eine mögliche
Fehlersuche.
Gruß oldmax
key_press heißt Taste gedrückt.
Ich muss aber dennoch schauen, ob ein Schalter angeschaltet wird, d.h.
gedrückt wird. Gleichzeitg müsste ich aber, wie du auch richtig
schreibst, prüfen, welche Taste losgelassen wird.
Jetzt bräuchte ich nochmal Hilfe.
Demnach müsste ich beide Funktionen abfragen oder? Also einmal will ich
ja wissen, ob eine zusätzliche Taste gedrückt wurde und das andere mal
ob eine zusätzlichte Taster "losgelassen" wurde (bzw. eben die Schalter
umgestellt wurden):
Daniel schrieb:> key_press heißt Taste gedrückt.> Ich muss aber dennoch schauen, ob ein Schalter angeschaltet wird, d.h.> gedrückt wird. Gleichzeitg müsste ich aber, wie du auch richtig> schreibst, prüfen, welche Taste losgelassen wird.
Ich denke, es wird Zeit, dass da mal etwas mehr zeigst.
Deine Angaben widersprechen sich da laufend immer wieder im Detail.
So wie das mehrheitlich klingt, interessiert dich ob eine Taste gedrückt
IST. Da ist aber dann get_key_press die falsche Funktion. Es gibt auch
Erweiterungen (werd gleich mal danach suchen) dieser Funktionalität, die
dir genau das richtige liefern. Die Funktion heisst dann get_key_state.
Die liefert dir, ob eine Taste genau jetzt gedrückt IST oder nicht.
> Jetzt bräuchte ich nochmal Hilfe.
Erst mal solltest du etwas konkreter werden, was du eigentlich mit den
Tasten gemacht wird.
get_key_press benutzt man, wenn das einmalige Drücken auf eine Taste zb
das Losfahren eines Rollos bewirken soll, wobei das Loslassen der Taste
keine spezielle Wirkung mehr hat. Oder wenn ein Tastendruck die
angezeigte Zahl auf einer Anzeige erhöhen soll. Oder wenn ein einmaliger
Tastendruck die Sekundeneinstellung an einer Uhr um 1 hochzählen soll.
Oder wenn ein einzelner Tastendruck das Garagentor aufmachen und ein
weitere Tastendruck das Garagentor zumachen soll.
Wenn es aber darum geht, dass eine gedrückte Taste zb eine LED
einschaltet und eine losgelassene Taste eine LED wieder ausschaltet
(oder Rollo Motor ein/aus, Garagentor fährt nur SOLANGE eine Taste
gedrückt IST) oder .... dann ist get_key_press die falsche Funktion.
Konfigurationsschalter sind üblicherweise von der letzteren Sorte. Ein
umgelegter Schalter bedeutet: Hintergrundbeleuchtung ein, ist der
Schalter in der anderen Position dann ist das: Hintergrundbeleuchtung
aus. Genau das ist aber NICHT das, wofür get_key_press gedacht ist. Du
brauchst das get_key_state (und das geh ich jetzt mal suchen)
> Im Programm möchte ich dann abfragen, welche Ports von PD0 bis PD3 auf> Masse liegen und welche nicht.
Die Entscheidung, ob du Entprellen musst oder nicht,
hängt davon ab, wie schnell, in welchen zeitlichen Abständen, du die
Tasten erfasst.
Erfasst du den Tastenzustand von der Widerholzeit her nur langsam
(langsamer als die Prellzeit der Taster, also so 10msec) dann siehst du
kein Prellen und musst nicht entprellen.
Erfasst du die Tasten schneller UND zählst Tastendrücke, wie oft sie
also von 1 auf 0 geht, dann musst du entprellen.
Zählst du die Tastendrücke (Wechsel von 1 auf 0) gar nicht, brauchst du
auch bei schnellerer Erfassung nicht zu etprellen.
oldmax schrieb:> Lothar Miller:>>Sonst dürfte man niemals mit einem Lichtschalter direkt ohne Entprellung>>ein Licht einschalten...> Seit wann ist eine Lampe ein µC...
Es ging nicht vorrangig um den uC, sondern um irgendwelche wie auch
immer geartete
> mechanische Schalter, ob Taster, Schützkontakt oder sonstwasoldmax schrieb:> Es sei denn, der Controller arbeitet noch mechanisch
Auch einen mechanisches Schrittschaltwerk (= Controller) bekommst du mit
einem geeignet prellenden Kontakt in die Irre geführt. Denn es kommt ja
nur drauf an, ob hinter dem Kontakt auf eine Flanke reagiert werden
soll (Zähler, FSM). Wenn nur und ausschliesslich auf den Zustand
reagiert werden soll, ist eine Entprellung nie nötig, denn der Weg
zurück zum Ausgangszustand ist der selbe wie der Hinweg.
Der einfachste Fall wäre: mit Tasterdruck eine LED schalten.
Muss dieser Taster entprellt werden? Nein, weil das Loslassen des
Tasters zum Ausgangszustand zurückführt. Und beim Prellen hüpft die LED
dann eben ein paar mal zwischen Hell und dunkel hin&her...
Hallo,
erst einmal nochmals an alle vielen Dank für die Unterstützung und Hilfe
Es sind Konfigurationsschalter die eingelesen werden sollen. Je nachdem
welche der Konfigurationsschaler geschaltet sind, habe ich bei den 4
Schalter 16 Möglichkeiten. Ich möchte dann die Werte von PD2 bis PD5
einlesen bzw. 2x rechts schieben, ausmarkieren und invertieren und so
beim dem Einlesen des Ports nach Schiebereien und Maskierereien einen
Zahlenwert von 0 bis 15 zu erhalten.
Je nach Zahl soll dann in einem switch verschiedene Dinge des Programms
konfiguriert werden.
Das ist die Grundfunktion, was ich erreichen will.
So wie ich das nun sehe, brauche ich dann get_key_state
Dann wäre das konrekt im meinem Vorhaben so zu erledigen:
1
uint8_tWertPORT=0;
2
ifget_key_state(((1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3))){// hat sich irgendein Status der 4 Tasten geändert
3
WertPORT=PIND;// Port einlesen
4
// hier kämen dann die Schiebereien und Maskiererein
5
WertPORT=WertPORT>>2;// 2 rechts schieben
6
// oberen 4 Bits maskieren, sodass diese gelöscht sind
7
WertPORT=WertPORT&0b00001111;
8
// Variable invertieren und zwar nur die unteren 4 bits
Daniel schrieb:> Hallo,>> erst einmal nochmals an alle vielen Dank für die Unterstützung und Hilfe> Es sind Konfigurationsschalter die eingelesen werden sollen.
Alles schön und gut.
Aber: WAS MACHEN SIE!
Genau das ist die Gretechenfrage. Erst wenn man das weiß, kann man
entscheiden, welches Vorgehen vernünftig ist.
> Je nach Zahl soll dann in einem switch verschiedene Dinge des Programms> konfiguriert werden.
Was muss man sich darunter vorstellen?
> Dann wäre das konrekt im meinem Vorhaben so zu erledigen:>>
Daniel schrieb:> Ich möchte dann die Werte von PD2 bis PD5> :> ( 1<<PD0 ) |( 1<<PD1 ) |( 1<<PD2 ) |( 1<<PD3 )
Hoppala....
Daniel schrieb:> So wie ich das nun sehe, brauche ich dann get_key_state
Nein. Du musst nur den Port einlesen, invertieren, um 2 Bits nach rechts
schieben und mit 0xf verunden. Fertig.
1
switches=(~PortD>>2)&0xf;
Denn einen Übergang z.B. von 3 nach 12 kannst du sowieso niemals
"entprellen"...
Karl Heinz Buchegger schrieb:> Alles schön und gut.> Aber: WAS MACHEN SIE!
Je nach Zahl die bei dem Einlesen herauskommt, wird unter anderem eine
Stelle eines Vektors geholt, z.B.
Vektor [WertPORT]
Darüber hinaus wird über ein Switch --> case (0), case(1), etc.
verschiedene Dinge angeschaltet z.B. eine LED.
Daniel schrieb:> verschiedene Dinge angeschaltet z.B. eine LED.
Und was passiert, wenn du langsam von 3 nach 12 umschaltest. Ist es dann
egal, ob beim "überfahren" von 7 jedesmal kurz die LED angeht?
Daniel schrieb:> Eine Frage hätte ich trotzdem noch:> Was liefert get_key_state() als Wert zurück bzw. was tut die Funktion> genau?
Sie funktioniert in der Hinsicht genau wie get_key_press.
Sie liefert dir einen Wert, in dem ein 1 Bit anzeigt, ob die
angeforderte Taste momentan gedrückt ist oder nicht.
Probiers einfach aus.
Verkabel 8 LED an einen anderne Port und leg das Ergebnis von
get_key_state einfach auf diesen LED_Port. Dann siehst du es, was dir
die Funktion liefert.
Und ehe du fragst: mit dem Argument legst du fest, welche der Schalter
dich überhaupt interessieren.
Aber wie schon gesagt: Wenn das alles sowieso nicht kritisch ist, dann
kannst du dir den ganzen Aufwand auch sparen. Wenn es keine Rolle
spielt, ob zwischendruch mal der Lüfter angeht, nur weil der
Konfigurierer von LED1 auf LED2 weiter durchschaltet, dann spielt es
auch keine Rolle, wenn nach dem Erreichen der 12 (für LED2) die LED beim
Schalten selber einmalig ganz kurz blinzelt.
Sie liefert den entprellten Pegel des entsprechenden Pins zurück. Diese
Routine funktioniert natürlich nur zusammen mit dem Rest von PeDas
Tasterentprellung...
Also ich habe das mal so nachgestellt, wie geschrieben hat:
1
PORTWert=(get_key_state((1<<PD2)|(1<<PD3)|(1<<PD4)|(1<<PD5))>>2);// Port D PD2 bis PD5 einlesen und 2 rechts schieben
2
PORTC=PORTWert;// eingelesene Werte in Port C schreiben für LEDs
An Port C hängen LEDs mit active low.
Nun passiert folgendes, je nachdem wo ich den Schaler durchschalten
lasse gegen Masse, geht am entsprechenden gegenüber an Port C (PD2 -->
PC0, PD3 --> PC1, etc.) die LED an.
Somit liest die Funktion get_key_state() den Wert der angegeben key_mask
ein und gibt, wenn gibt die key_mask wieder zurück mit einer 1 an der
Stelle wo Masse anliegt und eine 0 an der Stelle wo 5V (high-Pegel
anliegt). So sagen mir das zumindest meine LEDs.