Hallo Ich bin seit geraumer Zeit daran für meinen Drehgeber eine Routine zu schreiben mit welcher ich die Drehrichtung bestimmen kann. Doch ich habe unglaublicherweise einfach keinen Erfolg. Der Drehgeber besitzt zwei Ausgangssignale, wobei das erste Signal ausgelöst wird sobald die Optik auf der inkrementscheibe von schwarz auf weiss oder weiss auf schwarz wechselt, das zweite signal folgt dem ersten mit 90° Phasenverschiebung. Mit diese Informationen muss es "anscheinend" möglich sein die Richtung zu bestimmen. Zuerst probierte ich die einfachste Variante: Falls (SignalA = High AND SignalB Low) -> rechts Falls (SignalA = High AND SignalB High) -> links Ich bemerkte aber schon bald das sich dieses Verfahren bei leichtem hin und herbewegen des Drehgebers nicht bewährt. Ich habe nun schon unzählige Möglichkeiten probiert und theoretisch aufgezeichnet doch funktioiern tut alles nicht. Weiss jemand wie man die Signale auswerten muss (Wahrheitstabelle), dass die Richtung immer und ohne Zweifel bestimmt werden kann? Vielen Dank Dani
DRG_INP: ;Wartet auf Drehgeber-Impulse u.entscheidet l/r ;wartet, bis alle 2 Flanken auf high sind ;................................................................. WAIT_DRG_HIGH: LE PIND, DREHG_UP ;wartet auf high an beiden Drehgeber-Eingängen UE PIND, DREHG_DWN ; wdr brtc WAIT_DRG_HIGH ;Schleife, bis alle Eingänge high sind ;................................................................. WAIT_ON_LOW: LNE PIND, DREHG_UP ;warte auf ein LOW an den Drehgebereingängen brts DRG_UP ; LNE PIND, DREHG_DWN ; wdr brts DRG_DWN rjmp WAIT_ON_LOW ;Schleife bis Eingang low ist ;.................................................................. DRG_UP: LNE PIND, DREHG_DWN ;wartet bis 2-Kanal auch low ist ! brts CNT_UP ;falls ja, kann gezählt werden LE PIND, DREHG_UP ;falls 1.Kanal wieder high ist war es Spike brts WAIT_DRG_HIGH ;Spike falls PIN wieder high wdr rjmp DRG_UP ;................................................................... DRG_DWN: LNE PIND, DREHG_UP ;wartet bis 1-Kanal auch low ist ! brts CNT_DWN ;falls ja, kann gezählt werden LE PIND, DREHG_DWN ;falls 2.Kanal wieder high ist war es Spike brts WAIT_DRG_HIGH ;wieder def.Lage suchen wdr rjmp DRG_DWN ;Loop ;...............................................;aufwärts zählen........................ CNT_UP: rcall INC_DG rjmp WAIT_DRG_HIGH ;auf Low an beiden Eingängen warten ;................................................;abwärts zählen........................... CNT_DWN: rcall DEC_DG rjmp WAIT_DRG_HIGH ;auf Low an beiden Eingängen warten ;*********************************************************************** *************
Hallo Josef Vielen Dank für die schnelle Antwort, ich vergass jedoch zu erwähnen dass ich in Ansi-C codiere, darum ist es für mich nicht gerade einfach hinter die Lokig von deinem Code zu kommen. Ausserdem arbeite ich mit den Externen Interrupt von dem uC, d.h. bei den Fallenden Flanken möchte ich entscheiden in welche Richtung gedreht wird, ich habe dazu noch ein FlipFlop eingebaut um die Logik bei der letzten gestiegenen Flanke noch zur Verfügung zu haben, doch trotz all den Mitteln habe ich bis jetzt noch nicht die Richtige Abfrage gefunden. Gruss Dani
Hallo Dani, die Auswertung von Positionsgebern sollte man nicht mit flankengetriggerten Interrupts machen ! Steht der Geber zufällig genau auf einem Signalwechsel kann es zur Oszillation mit hoher Frequenz kommen (Vibration, Rückkopplung ?). Dann bekommst Du Interrupts ohne Ende und Deine Hauptprogrammroutine kommt nicht mehr zum Zuge. Deshalb habe ich die Abfrage mit einem Timerinterupt gelöst, da dann keine unzulässig hohe Interruptrate auftreten kann (ist ja konstant, da vom Timer). Das die Timerfrequenz kleiner ist als solche Oszillationen, hat keinen Einfluß auf die Genauigkeit. Sie muß nur immer größer sein, als die echte Positionsänderung. In meiner Anwendung taste ich mit etwa 20kHz ab. Der Code ist in C im Anhang. Peter
Auch ne Alternative: die Signale per Hardware dekodieren und getrennte Taktsignale bzw. Takt und Richtung an den MC senden.
Wichtig ist, dass dein Programm erkennt, wenn der Drehgeber steht bzw.ein vorangegangenes Zählen abgeschlossen wurde, also kein Signal auf beiden Ausgängen von ihm ausgegeben wird (beide Ausgänge high). Das ist immer (!) dein Ausgangspunkt. Sobald eine Flanke kommt, wird abgefragt welche (entscheidet links oder rechts).War sie zB rechts als erstes da, verzweigst du in die "Rechtsroutine". In dieser wartest du auf den zweiten Eingang. Dann kannst du 1 Impuls zählen. Danach wartest du wieder, bis alle 2 Ausgänge wieder auf high sind (Drehgeber steht bzw 1 Impuls vorbei) Ob Interrut oder Timer ist nicht so wichtig. Für den Anfang wäre es besser, die Pins zu pollen. Nur so ist die höchstmögliche Arbeitsgeschwindigkeit möglich. Meisten muss man die gezählten Impulse vom Drehgeber noch durch einen Faktor teilen um ein Ergebnis zu erhalten, dass weiterverarbeitet werden kann. Gutes Gelingen Josef
Hallo Leute Ich habe mir nun die Gray.c51 Software von Peter zu gemüte geführt. Das ganze funktioniert einwandfrei (copy-paste)!! Und ich habe mich tagelange mit einer Lösung über die Externen Interrupts rumgeschlagen. Ich habe allerdings zuerst mal auf den Timerinterrupt verzichtet und mit die Rutine einfach ins Main gehängt, dass funktioniert aber so gut, dass ich es dabei belassen werde. Also nochmals vielen Dank an euere Hilfe und die geniale C-Source von Peter Dani
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.