mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Drehgeber - (wiedereinmal)


Autor: jaja...derhenne (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
habe einen Drehgeber mit A und B Signal (2 Bit) an PD2 und PD3
angeschlossen und möchte einen counter rauf oder runterzählen.
Dafür wird die erste Stellung einmal eingelesen und der Gray-Code in
Binär-Code umgewandelt, danach wird erneut die Position eingelesen und
dann mit der alten verglichen.
Bei der Gray/Binär-Umwandlung wird das MSB (Bit 1)so wie es ist
übernommen und das LSB(Bit 0) durch XOR-Verknüpfung des LSB mit dem MSB
bestimmt.

Der Code funktioniert aber nicht so, wie ich es möchte.
Muss man einen Timer-Interrupt dafür starten ??
Wenn ja, warum ?
Vielleicht kann mir jemand Verbesserungen vorschlagen
oder die Fehler nennen.
Habe die anderen Post im Forum schon gelesen, wollte aber was in
Assembler und nicht in C programmieren.

Autor: condor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo

wenn dir jemand bei der lösung geholfen hat wäre es super wenn du dein
ASM hir nochmal einspielen würdest. ich suche nänlich aus so was...

hofendlich weiß dir jemand rat

Autor: Moritz (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
moin

hab zwar nicht ganz verstanden wie du das gemacht hast. hab aber vor
einer woche was ähnliches geschrieben. hat auch erst ewig nich
funktioniert, bis ich gemerkt hab das der drehgeber nich richtig
festgelötet war. jetzt funktionierts dafür um so besser. anbei mein
progrämmchen. die sache mit dem drehgeber (rotator) steht relativ weit
oben. ich benutz den int 0 (PD3) zum auslesen, müsste aber auch mit
polling funktionieren.

Autor: krassXXL (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi,derhenne

hast du vielleicht in C-Programm? Wenn ja kannst du mir vielleicht zu
schicken?

Autor: Johnny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guckst Du hier ab Seite 33:
http://www.jogy.ch/files/Circuit_Cellar_Design_Con...

Ich hab beim Terminal zu meinem farbigen Propeller Display einen
Drehgeber verbaut um Buchstaben auszuwählen.
Eine Kurzbeschreibung ist hier zu finden:
http://www.jogy.ch/German/electronic.html

Gruss
Johnny

Autor: TravelRec. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn das ein Drehgeber ist, wie ich ihn kenne, dann ändert, je nach
Drehrichtung, immer ein Pin zuerst seinen Pegel gegenüber dem anderen.
Nun, dann würde ich diesen Pin, in der Regel Pin A, mit einem
Interruptpin des Controllers verbinden. Der Interrupt wird auf
Pin-Toggeln eingestellt. In der ISR überprüft man dann den Pegel des 2.
Pins, ist dieser (noch) Low, wurde in die eine Richtung gedreht, ist er
(noch) high, wurde in die andere Richtung gedreht. Dann muß man noch
ein Flag setzen, welches die Abfrage des Encoders innerhalb der
nächsten 30ms verhindert, damit man das Prellen nicht mit abfragt, und
dann sollte das schon klappen. Bei meinem "C....d" - Encoder funzt
diese Praxis sehr schön.

Autor: Johnny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Per Port-Interrupt kriegt man das nicht vernünftig zum funktionieren.
Besser eine kleine State-Maschine programmieren und die beiden Pins in
einem Timer-Interrupt pollen.
Ich habe viel experimentiert und mit der State-Maschine funktionierte
es schlussendlich perfekt.

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Such in der Codesammlung nach Peter Danneggers Lösung !

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wasn alter Thread...

Autor: Jan B (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Drehgeberauswertung per Interrupt ist nicht zu empfehlen.
Das Prellen bei mech.Drehgebern oder auch das "Zittern" um eine
Position bei opt.Drehgebern führt leicht zu Zählfehlern oder gar
zu einem Stacküberlauf, weil zu viele Interupts in zu kurzer Zeit
aufgerufen werden.

Hier ein Beispiel für eine Drehgeberauswertung per Polling.
Das Codebeispiel ist in ASM, aber wegen der Kürze einfach zu
verstehen und in andere Sprachen zu übertragen.

Gruß Jan

Autor: TravelRec. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte doch oben gerade erwähnt, daß der Interupt nach der ersten
Erkennung für ca. 30ms gesperrt wird. Damit wird das Drehgeberprellen
ausmaskiert und Doppelinterrupts ausgeschlossen. Nach der allerersten
Erkennung eines Pegelwechsels wird der Pinstatus in der ISR
festgestellt, der selbst bei fiesem Prellen stimmt, da der Interrupt
unmittelbar nach Pegelwechsel (egal wohin) ein einziges Mal zugelassen
wird. Da der 2. Pin technisch bedingt erst viel später den Pegel
wechselt, ist alles bereits vergessen, bevor irgendeine Prellspitze das
Ergebnis versauen könnte. Allen Zweiflern sei gesagt, daß dies hier auch
bei schnellem Rotieren sehr gut funktioniert.

Autor: Johnny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
TravelRec, das ist Quatsch, ich habs selbst ausprobiert. Stell Dir mal
vor, dass einer kontinuierlich den Drehgeber dreht. Nun wird der erste
Takt zwar korrekt erkannt und gezählt mit Deinem Port I/O Interrupt.
Dann sperrst Du den IRQ und gibst ihn nach der Prellzeit wieder frei.
Nun, da sich der Drehgeber jetzt bewegt, ist es nun reiner Zufall,
welches Signal des Drehgebers als nächstes "ausschlägt", wenn der IRQ
wieder freigegeben worden ist. Also weisst Du nicht, ob es sich nun nach
links oder rechts gedreht hat.
Mit Deiner Lösung und wenn man den Drehgeber konstant rel. zügig dreht,
springt der Zählerstand zufällig vorwärts und rückwärts oder bleibt gar
stehen.

Daher ist die State-Maschine nötig, welche durchlaufen werden muss,
damit ein Zählschritt ausgelöst wird. Dadurch findet gewissermassen
eine kleine Plausibilitätskontrolle statt.

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das stimmt, Johnny hat recht. Kurze Überschlagsrechnung dazu:

Wir nehmen mal an, dass der Drehgeber 32 Rastungen hat. Bei einer
Drehung von einer Rastung zur nächsten treten mindestens zwei gültige
Impulse auf (Signal A: up/down, Signal B: up/down). Macht pro ganzer
Umdrehung 64 Impulse. Wenn Du die Umdrehung in einer Sekunde machst,
liegen zwischen den Impulsen 1/64 = 0,03125 Sekunden, also gut 30ms.
Das wird dann aber ganz schön knapp mit der Interruptsperrung für
30ms...

Autor: TravelRec. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Macht doch wie ihr denkt - wenn ich Probleme mit meiner Lösung bekomme,
mach ich´s auch so. Schluß mit der Rauferei ;-)

Autor: Johnny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, Frieden :-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.