Hallo mitteinander, ich habe hier einen EC11B Drehgeber an einem ATMEGA8 PB1=A PB0=B werden gegen Masse gezogen if ((PINB&(1<<PB1))==0) //Wenn A auf 0 geht (R oder L drehen) { if ((PINB&(1<<PB0))==1) ++out; //Wenn A=0 und B=1 erhöhe out if ((PINB&(1<<PB0))==0) --out; //Wenn A=0 und B=0 erniedrige out while ((PINB&(1<<PB1))==0)lcd_send(out);//Warte so lange bis A wieder 1 ist } Scheint mir eine gute Lösung zu sein, funktioniert bei mir gut und schnell. Die anderen Lösungen scheinen sehr umständlich zu sein. Die Int braucht man auch meistens für was anderes. Hab ich da was übersehen ?? Gruß Boris (Anfänger, geringe C Kenntnisse)
Boris Hightech schrieb:
> Hab ich da was übersehen ??
Das die Kontakte im Drehgeber irgenwann anfangen werden zu prellen.
Prellen spielt ja hier keine große Rolle da ja hier auf die Flanken geschaut wird. D.h. Wenn A auf 0 geht tut sich was, und dann tut sich erst wieder was nachdem A auf 1 war. Im schlimmsten Fall zählt er mal 2 statt 1 und das ist bei einem Hand bedienten Drehgeber ja nicht so schlimm.
Nochmal ganz in kurz: #define A ((PINB&(1<<PB1))==0) #define B ((PINB&(1<<PB0))==0) if A { if B ++out; else --out; lcd_send(out); while A; } kürzer gehts nimmer
Boris Hightech schrieb: > Prellen spielt ja hier keine große Rolle da ja hier auf die Flanken > geschaut wird. D.h. Wenn A auf 0 geht tut sich was, und dann tut sich > erst wieder was nachdem A auf 1 war. Du möchtest dich eventuell mal darüber informieren, wie sich Prellen an den überwachten Portpins auswirkt. Du drehst um 1 Rastung weiter, dein Programm sieht aber mehrere 0-1-0-1-0-1 Übergänge, bis sich der Wert dann endlich auf 1 stabilisiert hat. Sprich: Deine 'while(A);' Schleife ist nutzlos gegenüber Prellen. > Im schlimmsten Fall zählt er mal 2 statt 1 und das ist bei einem Hand > bedienten Drehgeber ja nicht so schlimm. Wenn ich so ein Teil vor mir habe und ich drehe um 1 Rastung und der Wert verändert sich einmal um 1, dann um 5, dann um 3 und zu guter letzt bei der nächsten Rastung um 4; weißt du was ich dann mit dem Teil mache?
Vlad Tepesch schrieb:
> beschreibs mal ausführlich ;-P
...
dann geh ich in mein Werkzeugkammerl und hole den grossen
Vorschlaghammer. Meine Freundin hat dann ob meiner Schimpftiraden auf
den Programmierer wieder eine Menge zu lachen ...
:-)
Jaaaa.... aber.... wenn der Eingang etwas sieht, dann folgt ja auch erstmal eine Aktion, wie z.B. Ausgabe des Wertes auf das Display lcd_send(out), des dauert ja auch mal nen paar ms, dann ist das Prelle ja eh vorbei. Und während dessen tut er ja auch nix vom Port einlesen. Erst wenn die Aktion beendet ist, gehts ja weiter mit while A
> aber.... > wenn der Eingang etwas sieht, dann folgt ja auch erstmal eine Aktion, > wie z.B. Ausgabe des Wertes auf das Display lcd_send(out), des dauert ja > auch mal nen paar ms, dann ist das Prelle ja eh vorbei. Nööö... Wenn Du so programmierst, dass die Ausgabe sofort (ohne Veratbeitung) der Eingabe folgt, dann machst Du was verkehrt. Eingaben wie Taster und Drehgeber fragt man zyklisch (durch Timer-Int synchronisiert) ab und sichert deren Werte global. Die Mainloop (oder eines ihrer Module) prüft dann (bei passender Gelegenheit) diese Werte, reagiert darauf und entwertet (löscht) sie. ...
Du meinst ich soll in den Timer int schreiben: gucke mal alle Ports nach wo Taster / Drehgeber dran hängen ? Z.b. so alle 1ms 1 mal gucken ?
> Du meinst ich soll in den Timer int schreiben: gucke mal alle Ports nach > wo Taster / Drehgeber dran hängen ? > Z.b. so alle 1ms 1 mal gucken ? Im Prinzip ja, nur nicht so primitiv, wie Du es darstellst. Schau doch einfach mal ins Tutorial, da gibt es recht effiziente Algorithmen für. Da ich kein C kann (ich werkele in ASM), kann ich Dir keine konkreten C-Tips geben. Aber das Abfragen von manuell betätigten Drehgebern und Entprellen von Tastern benötigt bei halbwegs effizientem Code nicht viel mehr als 1% der AVR-Rechenleistung. ...
Boris Hightech schrieb: > wenn der Eingang etwas sieht, dann folgt ja auch erstmal eine Aktion, > wie z.B. Ausgabe des Wertes auf das Display lcd_send(out), des dauert ja > auch mal nen paar ms, dann ist das Prelle ja eh vorbei. Genau das ist es, was deinen Code momentan rettet. Nur was, wenn ich eben nicht auf ein LCD ausgebe, sondern zb den counter einfach nur auf einen Port rausgebe (weil dort zb ein paar LED sitzen)? Es ist unklug, eine Routine als das beste seit geschinttenem Brot anzupreisen, die nur dann funktioniert, wenn man mitten drinn eine Zahl-ASCII Umwandlung samt LCD-Ausgabe machen muss, damit sie funktioniert :-)
Boris Hightech schrieb: > wenn der Eingang etwas sieht, dann folgt ja auch erstmal eine Aktion, > wie z.B. Ausgabe des Wertes auf das Display lcd_send(out), des dauert ja > auch mal nen paar ms, dann ist das Prelle ja eh vorbei. Mit dieser Einstellung wirst Du schnell Schiffbruch erleiden. Man kann nicht vernünftig programmieren, wenn die Mainloop nur eine ganz bestimmte Durchlaufzeit haben darf (zu kurz -> Preller, zu lang -> Impulsverlust). Wenn die Programme auch nur etwas größer werden sollen und wenn man nicht bei jedem Projekt total von Null anfangen will, muß man so programmieren, daß die einzelnen Tasks sich nicht gegenseitig stören. Man programmiert eine Task und dann vergißt man sie. D.h. nachdem sie funktioniert, verwendet man sie nur noch. Peter
Noch was: Was passiert in Deinem Programm, wenn A zwar auf 0, nicht jedoch wieder auf 1 springt? Um das Programm weiter laufen zu lassen, ist dann erstmal ein kleiner Schups am Drehgeber notwendig (so wie man auf ein Barometer klopft).
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.