Quadraturdecodierung


7

Ich habe 6 hochauflösende Encoder (10k Zeilen), die ich mit einem Mikrocontroller verbinden möchte. Ich habe Code geschrieben, um die Quadraturdecodierung für alle Encoder durchzuführen, aber es gibt einfach keine Möglichkeit, dass ein schlechter Arduino so viele Encoder mit einer angemessenen Geschwindigkeit handhaben kann, geschweige denn irgendetwas anderes tun kann, während er die Encoder verfolgt.

Was soll ich in einer solchen Situation tun?

Leider habe ich nicht viel Hintergrundwissen in der Elektronik, nur in der Programmierung (nur ein bisschen).


2
Wie schnell ist es, dh wie viele Zählungen pro Sekunde erhalten Sie?
Starblue

Antworten:


14

Mein Haustier ärgert sich, wenn die Quadraturdecodierung in Software durchgeführt wird. In der Software kann der Decoder häufig nicht mithalten, insbesondere wenn die Pulsfrequenz schnell ist oder die MCU viele andere Dinge tut. Ich habe viele Geräte gesehen, die Quadraturcodierer an einem Dateneingabeknopf verwenden, und es funktioniert die meiste Zeit einwandfrei. Der Decoder übersprang jedoch Impulse, wenn die MCU etwas tun musste, z. B. den Bildschirm aktualisieren oder über RS-232 sprechen.

Ich mache Quadraturdecodierung in einem FPGA. Ein 50K Gate Xilinx Spartan-3A kostet weniger als 10 US-Dollar und kann mehr Kanäle dekodieren als Pins. Und das mit einer Quadraturpulsfrequenz über 1 MHz. Es gibt keine MCUs für ähnliche oder günstigere Kosten, die dies tun können.

Bearbeiten: Was unten folgt, ist eine Zusammenfassung vieler Kommentare und einige weitere Ausführungen von meiner Seite. Genießen!

Es ist wahr, dass Sie einen Software-Ansatz durchführen können, wenn die Pulsfrequenz langsam genug ist. Wenn dies erledigt ist, müssen Sie sicherstellen, dass die "Eckfälle" abgedeckt sind. Dinge wie Interrupts für andere Peripheriegeräte (wie UARTs, ADCs usw.) können beeinflussen, wie oft Sie die Quadraturdaten abtasten, wodurch der Quadraturdecodierungsprozess gelegentlich Impulse verfehlt. Diese fehlenden Impulse sind für einige Anwendungen, wie z. B. einen Dateneingabeknopf, "in Ordnung", stören mich aber immer noch.

@Leon Heller mag die XMOS-Prozessoren für so etwas wirklich . Für diejenigen, die es nicht wissen, ist das XMOS-Zeug im Grunde eine einfache, aber superschnelle MCU. Wo die meisten MCUs im Bereich von <25 MIPS laufen, drängt das XMOS-Zeug auf 500 MIPS. XMOS macht nicht viele hardwarebasierte Peripheriegeräte wie UARTs. Stattdessen "bit-bang" sie es und machen den UART in Software. Sie bieten auch Dinge wie USB und 10 MBit / s Ethernet. Ok, ich vereinfache das sehr, aber du verstehst, worum es geht. Hier ist meine Meinung: Es gibt FPGA-Leute und es gibt CPU-Leute. Wenn Sie ein CPU-Typ sind und keine FPGAs mögen, ist der XMOS-Prozessor möglicherweise das Richtige für Sie.

Das Thema Gray-Codes in einer FPGA-Implementierung wurde angesprochen und die Up / Down-Positionszähler in Gray-Code implementiert. Es gibt normalerweise zwei Gründe für die Verwendung von Gray-Codes: Wenn eine asynchrone Logik ausgeführt wird (2 oder mehr Takte) oder wenn die Zähler weniger Logik benötigen. Normalerweise hätten Sie keine asynchrone Logik im FPGA (außer das Abtasten der Quadraturdaten an den Eingangspins), und das FPGA verfügt bereits über superschnelle Übertragsketten (auch als binäre Addierer bezeichnet). Unter normalen Umständen sind hierfür keine Gray-Code-Zähler erforderlich.

Sie können hierfür anstelle eines FPGA eine CPLD verwenden. Dies würde für 1 oder 2 Quadraturdecoder funktionieren, aber wenn Sie mehr Decoder hinzufügen, wird die Schnittstelle zu einer MCU komplexer. FPGAs sind dafür gut geeignet, da die MCU-Schnittstelle SPI oder eine andere einfache Sache sein kann, die nicht Dutzende von Pins auf der MCU belegt.

Der "richtige" Weg, dies in einem FPGA zu tun, besteht darin, dass das FPGA einen einfachen 8-16-Bit-Zähler hat, der die Position verfolgt. Dieser Zähler wird nach der Initialisierung nie und manchmal auch dann nicht zurückgesetzt. Software (SW) fragt diese Position von Zeit zu Zeit ab und zeichnet die "vorherige Position" auf. Wenn Sie die aktuelle Position nehmen und die vorherige Position subtrahieren, wird der Software mitgeteilt, wie weit sich die Position geändert hat.

Der Grund, warum der Positionszähler niemals zurückgesetzt wird, ist, dass wir versuchen, ein "destruktives Lesen" zu vermeiden. In diesem Fall liest die CPU ein Register, wodurch etwas Irreversibles passiert - beispielsweise das Löschen eines Positionszählers. Manchmal sind destruktive Lesevorgänge unvermeidlich, wie beim Lesen eines FIFO, aber im Allgemeinen möchten Sie sie vermeiden. Das Denken dahinter geht über diesen Beitrag hinaus. Ich habe versucht, eine gute Webseite zu finden, auf der sie besprochen werden, aber ich bin gescheitert. Es tut uns leid.

Wenn ich unten über die Zählrate spreche, meine ich, wie schnell der Positionszähler nach oben oder unten gehen kann. Aufgrund der Quadratur der Sache beträgt die "Pulsfrequenz" ein Viertel der Zählrate. Ich gehe davon aus, dass wir für jeden vollen Puls viermal hoch / runter zählen können. Ich weiß, dass es andere Möglichkeiten zum Zählen gibt (eine Zählung pro vollem Impuls), aber ich ignoriere sie aus Prinzip.

Ohne Berücksichtigung des XMOS-Prozessors (der im Kontext der nächsten Absätze eher einem FPGA ähnelt) werden MCUs auf eine maximale Zählrate von weniger als 500 Hz und in vielen Fällen von weniger als 100 Hz begrenzt. Natürlich kann es einige Ausreißer geben, die höher als 1 kHz werden, aber für die meisten Menschen ist das schwierig. Für Ihre typische MCU ist es gut, über 100 Hz zu kommen, vorausgesetzt, die MCU ist nicht für die Quadraturdecodierung vorgesehen.

Ein typischer Dateneingabeknopf hat 12 bis 20 Impulse pro Umdrehung oder 48 bis 80 Zählungen pro Umdrehung. Angenommen, der Knopf hat einen Durchmesser von 1 Zoll, könnte eine typische, aber übereifrige Person etwa 4 Umdrehungen pro Sekunde erzielen, wenn sie versucht, durch viele Daten zu scrollen. Das entspricht einer Zählrate von 192 bis 320 Hz. Immer noch im Rahmen einer MCU, aber nur knapp und nur mit sorgfältiger Programmierung.

Ein FPGA kann, abhängig davon, wie genau die Logik geschrieben ist, Zählraten von mehr als 100 MHz verarbeiten. Ich habe meine Logik für Zählraten von bis zu etwa 50 kHz geschrieben, aber sie kann viele Quadraturdecoder in sehr wenig Logik ausführen. In einem Xilinx Spartan-3-FPGA sind etwa 50 Slices und 1 Block-RAM erforderlich, um 32 bis 512 Decoder auszuführen (Ihnen gehen die Pins aus, bevor Ihnen die Logik ausgeht).

Also, was ist besser, FPGA, MCU oder XMOS? Wie immer kommt es darauf an. Dies hängt nicht nur von den üblichen Faktoren wie Zählrate und Anzahl der Decoder ab, sondern auch davon, was der Designer bequem verwendet und was sich sonst noch im System befindet. Ich bevorzuge FPGA, aber das ist genau der Typ, der ich bin! :) :)


Ich würde einige Überschriften und Formatierungsänderungen vorschlagen, um diese Antwort perfekt zu machen.
Kortuk

Ich mag Ihren Kommentar zu destruktiven Lesevorgängen, möchte ihn aber ergänzen: Wenn der Prozessor keinen atomaren Lesevorgang des Zählerwerts in voller Breite durchführen kann, ist es meiner Meinung nach sicherer, wenn "stückweise" Lesevorgänge Live-Daten abrufen, als wenn ein Teil gelesen wird verriegeln die anderen. Wenn die Lesevorgänge Live-Daten abrufen, kann der Prozessor Low-Byte / High-Byte / Low-Byte lesen und feststellen, dass die Daten gut sind, wenn die beiden Low-Byte-Werte übereinstimmen (wenn sie nicht übereinstimmen, versuchen Sie die Sequenz nochmal). Dieser Ansatz funktioniert auch dann, wenn während die Hauptleitung eine solche Sequenz ausführt, ein Interrupt auftritt und ihr Handler auch die Sequenz ausführt.
Supercat

Wenn die Hardware dagegen den gesamten Zähler zwischenspeichert und dann zulässt, dass der zwischengespeicherte Wert in Teilen ausgelesen wird, kann der Code vereinfacht werden, wenn sichergestellt werden kann, dass er nicht durch Code unterbrochen wird, der auch den Zähler lesen muss, aber wenn Der einfachere Code wird durch Code unterbrochen, der den Timer liest, bei dem er möglicherweise ausfällt. Beispielsweise speichert der Hauptzeilencode den Zeitgeberwert 0x03FF und liest die Hälfte davon. Dann speichert ein Interrupt 0x0400, liest den Zähler und kehrt zurück. Schließlich liest die Hauptzeile die andere Hälfte des Zählers und ergibt 0x0300 oder 0x04FF, je nachdem, welche Hälfte zuerst gelesen wurde.
Supercat

Übrigens frage ich mich, ob Mikrocontroller-lesbare Zähler einen Graycode auf "Byte-Ebene" implementieren, indem z. B. jedes Byte (oder jede lesbare Einheit) in Ein-Komplement-Form gemeldet wird, wenn das niedrigste Bit des nächsthöheren Bytes gesetzt ist. Ein solches Design würde sicherstellen, dass das Lesen aller Bytes des Zeitgebers und das Ausführen der erforderlichen xor-Operationen ein legitimes Lesen ergeben würde, es sei denn, zwischen dem Lesen des LSB und dem nächsten Byte traten mehrere Zählungen auf, selbst in dem Szenario, in dem ein Zähler zwischen z Werte 0x02FF und 0x300 [die als 0x02FF und 0x03FF gemeldet würden].
Supercat

3

Mein Vorschlag wäre, den Arduino Benutzeranwendungscode ausführen zu lassen und einfach mit 3 oder 6 anderen sehr kostengünstigen Mikrocontrollern zu sprechen, die die Quadraturdecodierung durchführen. Die Anzahl der externen Mikros hängt davon ab, wie gut sie in der Lage sind, einen solchen hochauflösenden Encoder bei einer bestimmten Geschwindigkeit zu decodieren. Die externen Mikros würden sich wie die in Mäusen verhalten - sie verfolgen das Delta der Encoderanzahl seit der letzten Positionsabfrage. Angenommen, Sie versuchen nicht, eine Positionsrückmeldung in Echtzeit für die Motorsteuerung mit geschlossenem Regelkreis durchzuführen, und möchten nur wissen, wo sich jeder Motor zu einem beliebigen Zeitpunkt befindet, könnte dies für Sie funktionieren. Verwenden Sie SPI oder I2C, um mit allen externen Mikros zu sprechen, und natürlich müssen Sie sich mit dem Counter-Rollover befassen, falls der Hauptcontroller (Arduino) regelmäßig keine Positionsaktualisierung anfordert.


Hmm, separate billigere Mikros würden trotzig funktionieren (und ist etwas, das ich vielleicht durchziehen könnte). Apropos separate Chips, eine Idee, ob sie dedizierte Quadraturdecodierungs-ICs herstellen? Ich denke, für meine Anwendung benötige ich nur Schnappschüsse von Encoderpositionen im Gegensatz zur Echtzeitverfolgung. Es ist nur wichtig, dass alle Encoderpositionen genau zur gleichen Zeit erfasst werden.
Gefälschte

2
Sie machen absolut Quadraturdecoder. Ich habe seit einiger Zeit keinen diskreten IC mehr dafür verwendet, aber ich denke, es war der HCTL-2000. Achten Sie genau auf die Bandbreite des IC oder des Mikros, das Sie möglicherweise zum Decodieren verwenden. 10k Linien / Drehung sind extrem hochauflösend, so dass ein zu schnelles Drehen der Welle sehr gut zu Zählverlusten führen kann. Wenn es Ihnen nichts ausmacht, welchen Encoder verwenden Sie?
Dave

1
Ohh hey schau! Sie machen 32-Bit-Zähler / Decoder. Das ist perfekt! Möglicherweise muss ich jedoch zuerst einen parallelen zu einem seriellen IC durchlaufen (Ausgänge in 4 8-Bit-Übertragungen, nicht genügend Pins auf dem Mikro für 6 von ihnen). 33 MHz Betrieb ist weit mehr als ich brauche. Ich verwende TRD-S2500-BD-Encoder.
Gefälschter

Würde es überhaupt helfen, die Dekodierung mit Logik durchzuführen und "Aufwärts" - und "Ab" -Pulse an das Arduino auszugeben?
Endolith

1
@endolith aber ich frage mich, ob das das arduino noch zu sehr belasten würde. Sie müssen dann sicherstellen, dass der Arduino diese schnellen Auf- / Ab-Impulse von 6 hochauflösenden Encodern erfassen kann, während er sich mit der Benutzer-App befasst.
Dave

2

Verwenden Sie einen XMOS XS1-L1-Chip im Wert von 7,50 USD, wobei sechs Threads die Decodierung durchführen - ein Thread für jeden Encoder:

http://www.xmos.com/

Das lässt zwei Fäden für andere Sachen.

Die von Digi-Key erhältliche XK-1A-Karte kostet nur 99 und wird mit dem XTAG-2-Debugger geliefert. Es enthält alles, was Sie brauchen. Die Entwicklungssoftware ist kostenlos, und ich glaube, ich habe Encoder-Software im Benutzerforum gesehen. Die 1600 MIPS XC-1A-Karte ist eine weitere Option und kostet ebenfalls 99.

Dies ist wahrscheinlich der einfachste und billigste Weg, dies zu tun.


2
Ähh, aus irgendeinem Grund denke ich nicht, dass dies als Anfänger-Hobby-Level mehr zählt.
Gefälschte

1
@Faken ein 10k Line Encoder ist nicht gerade ein Hobby-Level! Ich denke, 6 davon auf einem Mikro zu haben und zu erwarten, dass das Mikro sie liest, wenn es mit einer vernünftigen Winkelgeschwindigkeit gedreht wird, ist eine große Herausforderung. Fahren Sie Ihre Last direkt und benötigen eine wirklich hohe Auflösung?
Dave

1
Ja, ich verstehe, dass 10k-Encoder kein Hobby-Level-Zeug sind, aber um ganz ehrlich zu sein, der einzige Unterschied zwischen einem 10k-Encoder und einem 200-Zeilen-Encoder besteht darin, dass einer teurer ist, ansonsten funktionieren sie ziemlich gleich. Der Unterschied zwischen einem 16-MHz-Arduino und einem 500-MHz-XMOS ist nicht ganz so einfach.
Gefälschte

Ich muss wegen Spielproblemen beim Getriebe direkt fahren. Ich entwerfe eine auf 6 DOF-Verknüpfungen basierende Koordinatenmessmaschine. Bis auf die Elektronik, mit der ich zu kämpfen habe, ist alles erledigt.
Gefälschter

1
Ich denke, die Abwertung ist, weil Sie einen Quadratur-Decoder-Chip vorgeschlagen haben, der viel leistungsfähiger, komplizierter und teurer ist als der Chip, auf dem der Rest seines Geräts läuft.
Davr
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.