Aus RN-Wissen.de
Wechseln zu: Navigation, Suche
Rasenmaehroboter fuer schwierige und grosse Gaerten im Test

(INT0/1 oder Polling ?)
(Auswertung der Signale)
Zeile 55: Zeile 55:
  
 
====Auswertung der Signale====
 
====Auswertung der Signale====
* Bei der INT-Methode mit nur einer Flanke ist die Sache einfach: Es erfolgt ein Schritt, die Richtung zeigt der andere Kanal.  
+
Auch wenn bei der Benutzung von Interrupts schon eine Information da ist, welcher Kanal sich geändert hat (und ggf. auch in welche Richtung), sollte die Auswertung trotzdem wie beim Polling erfolgen: Die beiden Kanäle einmal Auslesen, und dann zusammen mit dem vorherigen Wert bestimmen ob es einen Schritt gab und in welche Richtung. So kann verhindert werden, dass durch zu schnelle Interrupts, z.B. durch kurzzeitige Störungen Schritte verloren gehen und Fehler entstehen.
 +
Sofern von Hand nötig, muss das Interruptflag vor dem Auslesen des Ports zurückgesetzt werden, so dass alle Änderungen nach dem Auslesen erfasst werden.  
  
* mit beiden Flanken muss man beide Kanäle lesen, aber die Sache ist auch nicht kompliziert:  
+
* Bei der Auswertung nur einer Flanke (also z.B. steigende Flanke von Kanal A) ist die Sache einfach: Es erfolgt ein Schritt, die Richtung zeigt der andere Kanal.
 +
* mit beiden Flanken eines Kanals ist die Sache auch nicht viel komplizierter:  
 
** A = B --> vorwärts
 
** A = B --> vorwärts
 
** A <> B --> rückwärts
 
** A <> B --> rückwärts
Wenn der µC diese Interrupt-Art zulässt, kann man damit auch Schrittfehler vermeiden.  
+
* Bei den Übergängen des anderen Kanals dreht sich die Richtung um.  
 
   
 
   
* Auswertung der Übergänge:Das kann man natürlich auf viele Arten machen. Je nach Sprache bietet sich  
+
Die Auswertung der Übergänge kann man natürlich auf viele Arten machen. Je nach Sprache bietet sich  
** "Select/Case" (Bascom) oder "switch/case" (GCC) an.  
+
* "Select/Case" (Bascom) oder "switch/case" (GCC) an. Als Beispiel das [[Bascom_Inside-Code#.28Quadratur-.29_ENCODER|Assembler-listing]] für die Bascom-ENCODER()-Funktion<br/>
Als Beispiel das [[Bascom_Inside-Code#.28Quadratur-.29_ENCODER|Assembler-listing]] für die Bascom-ENCODER()-Funktion<br/>
+
* IF THEN ELSE oder in C auch die bedingte Berechnung mit dem ? Operator an.
** Eine andere Möglichkeit ist es, die neuen und die vorhergegangenen AB Werte zusammenzufassen und als Index für einen Werte- oder Sprungtabelle zu verwenden. In einer solche Tabelle muss man allerdings auch die ungültigen AB Kombinationen belegen, damit das funktioniert.
+
* Eine andere Möglichkeit ist es, die neuen und die vorhergegangenen AB Werte zusammenzufassen und als Index für eine Werte- oder Sprungtabelle mit 16 Werten zu verwenden. In einer solche Tabelle muss man allerdings auch die ungültigen AB Kombinationen belegen, damit das funktioniert.
  
 
==Autoren==
 
==Autoren==

Version vom 9. Juni 2013, 21:39 Uhr

Drehgeber-Auswertung

Es gibt in RN-Wissen schon einige (sehr gute) Artikel über Drehgeber und Auswertungsvarianten. Denen will ich hier keine Konkurrenz machen.
Technisches findet man hier, Grundsätzliches über das Quadratur-Signal da, und Programm-Beispiele für Drehencoder gibt es auch
Ich möchte dem einige grundsätzliche Überlegungen zur Drehgeber-Auswertung hinzufügen, damit es einem Einsteiger leichter fällt, eine Auswahl für seine konkreten Anforderungen zu treffen.

Signalfolge

Zur Erinnerung:

Quad 0.png

Auswertung der Flanken

Gerade bei den AVR's bietet es sich an, das A-Signal an einen "Externen Interrupt" anzuschliessen. Da man meist auch zwei Drehgeber hat (für links u. rechts), kommt man da wunderbar mit INT0 u. INT1 aus.

Vorwärts

Bei einer Konfiguration "steigende Flanke" wird bei den dicken Pfeilen der Interrupt ausgelöst. Liest man in der ISR den B-Kanal, kann man daraus direkt die Richtung entnehmen (im Beispiel ist das ebenfalls "1") und auf den Schrittzähler 1 addieren.

Quad isr1.png

Richtungsumkehr

Wird nun die Drehrichtung geändert, wird die bis dahin fallende Flanke von A zur steigenden Flanke, und B ist zu diesem Zeitpunkt dann "0". Die Sache ist eindeutig, man kann nun von Schrittzähler eins abziehen.

Quad isr2.png

Dabei tritt aber natürlich eine Verschiebung auf. Wenn die Impulsfolge im Verhältnis zum zurückgelegten Weg gross ist, kann man das ignorieren, es geht ja letztlich meistens nur um ein paar Millimeter, und wo genau sich ein Drehgeber zwischen zwei Impulsen befindet, kann man ohnehin nie sagen.

Möglicher Fehler

Es gibt aber auch Situationen, wo es zu Fehlern kommt. Hier wird der zweite Interrupt noch ausgelöst und (richtig) als Schritt vorwärts gezählt. Dann bewegt sich der Geber etwas zurück, kommt aber nicht bis zu nächsten steigenden Flanke, sondern bewegt sich wieder nach vorne.

Quad err.png

Unsere Logik zählt nun einen Impuls zweimal, obwohl der drehgeber sich immer noch am selben Platz befindet.

Auswertung der Übergänge

(Genaugenommen der Zustände unmittelbar danach)
Die genaueste Auswertung ist möglich, wenn man alle Übergänge steigend/fallend von beiden Kanälen (A u. B) bewertet. Das kann man ebenfalls mit ISR's machen, wenn man den µC so konfigurieren kann, dass er beide Flankenarten auslöst. Da dafür aber nur ein ISR-Vektor zur Verfügung steht, muss man in der Routine sowohl Kanal A als auch B abfragen und auch, ob fallend oder steigend.
Am einfachsten merkt man sich immer den Zustand von A u. B und vergleicht mit dem neuen Abtastergebnis.
Im Grunde ist das dann dasselbe, als wenn man ohne ISR periodisch die Eingänge abtastet, was natürlich oft genug geschehen muss, damit nichts verlorengeht. Die Flanken selbst erkennt man an dem Unterschien AB / AB-alt.
In beiden Fällen erfolgt dann die Auswertung an den strichlierten senkrechten Linien.

Quad states.png

Vorwärts

Von dem Mitte nach rechts gelesen bekommt also an den bezeichneten Stellen die Werte

  • 00 vorher: 01
  • 10 vorher: 00
  • 11 vorher: 10
  • 01 vorher: 11
  • usw

Rückwärts

Von dem Mitte nach links gelesen bekommt dann an den bezeichneten Stellen die Werte

  • 00 vorher: 10
  • 01 vorher: 00
  • 11 vorher: 01
  • 10 vorher: 11
  • usw

Programmtechnische Umsetzung

INT0/1 oder Polling ?

  • Wie schon erwähnt, bei AVR's bieten sich die beiden "external interrrupts" geradezu an. Bei vielen fertigen Boards werden die notwendigen Leitungen schon für einen Anschluss herausgeführt. Bei neuere AVR µCs (z.B. Mega88) bietet sich der Pin-Change Interrupt an, der an allen Ports verfügbar ist. Die Hauptschleife (DO...LOOP) bzw. (while(true)) braucht sich dadurch nicht unbedingt um die Sache zu kümmern. Unpraktisch ist ein externer Interrupt, wenn es durch eine kleine Hysterese zu vielen Störungen kommen kann, wenn eine der Lichtschranken gerade an der Grenze ist. Man hat dann im ungünstigen Fall ein sehr hohe Interruptfrequenz und ggf. auftretende Schrittfehler werden zum Problem.

Bei Odometrie-Anwendungen gehen die oben erwähnten möglichen Schrittfehler meistens völlig in der Gesamt-Ungenauigkeit unter (schlupfende Räder etc.).
Hat man als Drehgeber ein Dateneingaberad ( z.B. für Menüs u. Parametereingaben) erfolgt ohnehin eine Sichtkontrolle der Position, da kommt es schon garnicht darauf an.

  • Die Sache liegt anders, wenn wirklich kein Tick falsch interpretiert werden soll, also z.B. bei Positionier-Anwendungen. Da ist es wohl besser, die Eingänge zu pollen und alle Übergänge auszuwerten.

Das kann man durchaus in der Hauptschleife machen, wenn dann die Abtastfrequenz ausreichend ist, man kann aber auch durch einen TIMER-Interrupt das Polling auslösen (mit dem gleichen Kriterium).

  • Ganz elegant ist natürlich eine Mischform: wenn man auch die Geschwindigkeit misst, kann man abhängig davon die Methode ändern, denn die genannten Schrittfehler werden bei höherem Tempo kaum auftreten, eher bei Stillstand, genauso, wie auch die Geschwindigkeitsmessung selbst wechseln kann zwischen "schritte in der Zeit" und "Zeit je Schritt".

Auswertung der Signale

Auch wenn bei der Benutzung von Interrupts schon eine Information da ist, welcher Kanal sich geändert hat (und ggf. auch in welche Richtung), sollte die Auswertung trotzdem wie beim Polling erfolgen: Die beiden Kanäle einmal Auslesen, und dann zusammen mit dem vorherigen Wert bestimmen ob es einen Schritt gab und in welche Richtung. So kann verhindert werden, dass durch zu schnelle Interrupts, z.B. durch kurzzeitige Störungen Schritte verloren gehen und Fehler entstehen. Sofern von Hand nötig, muss das Interruptflag vor dem Auslesen des Ports zurückgesetzt werden, so dass alle Änderungen nach dem Auslesen erfasst werden.

  • Bei der Auswertung nur einer Flanke (also z.B. steigende Flanke von Kanal A) ist die Sache einfach: Es erfolgt ein Schritt, die Richtung zeigt der andere Kanal.
  • mit beiden Flanken eines Kanals ist die Sache auch nicht viel komplizierter:
    • A = B --> vorwärts
    • A <> B --> rückwärts
  • Bei den Übergängen des anderen Kanals dreht sich die Richtung um.

Die Auswertung der Übergänge kann man natürlich auf viele Arten machen. Je nach Sprache bietet sich

  • "Select/Case" (Bascom) oder "switch/case" (GCC) an. Als Beispiel das Assembler-listing für die Bascom-ENCODER()-Funktion
  • IF THEN ELSE oder in C auch die bedingte Berechnung mit dem ? Operator an.
  • Eine andere Möglichkeit ist es, die neuen und die vorhergegangenen AB Werte zusammenzufassen und als Index für eine Werte- oder Sprungtabelle mit 16 Werten zu verwenden. In einer solche Tabelle muss man allerdings auch die ungültigen AB Kombinationen belegen, damit das funktioniert.

Autoren

Siehe auch


LiFePO4 Speicher Test