Forum: Mikrocontroller und Digitale Elektronik Drehgeber auslesen


von Boris H. (Firma: omfbv) (hightech75)


Lesenswert?

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)

von Klaus W. (mfgkw)


Lesenswert?

> Hab ich da was übersehen ??

Evtl. das Tutorial http://www.mikrocontroller.net/articles/Drehgeber

von Karl H. (kbuchegg)


Lesenswert?

Boris Hightech schrieb:

> Hab ich da was übersehen ??

Das die Kontakte im Drehgeber irgenwann anfangen werden zu prellen.

von Boris H. (Firma: omfbv) (hightech75)


Lesenswert?

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.

von Boris H. (Firma: omfbv) (hightech75)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

Hi

>...while A;
>    }
>kürzer gehts nimmer

Länger aber auch nicht.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

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?

von Vlad T. (vlad_tepesch)


Lesenswert?

beschreibs mal ausführlich ;-P

von Karl H. (kbuchegg)


Lesenswert?

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  ...

:-)

von Boris H. (Firma: omfbv) (hightech75)


Lesenswert?

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

von Hannes Lux (Gast)


Lesenswert?

> 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.

...

von Boris H. (Firma: omfbv) (hightech75)


Lesenswert?

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 ?

von Hannes Lux (Gast)


Lesenswert?

> 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.

...

von Karl H. (kbuchegg)


Lesenswert?

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 :-)

von Peter D. (peda)


Lesenswert?

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

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.