Dieses Kapitel enthält Details zu den Kernfunktionen von LinuxCNC, die ein genaues Timing für

  • die Erzeugung von Signalen, die von der Hardware (z. B. Motoren) interpretiert werden, oder

  • für die Interpretation der von der Hardware gesendeten Signale (z. B. Encoder).

1. StepGen

Diese Komponente ermöglicht die softwarebasierte Erzeugung von Schrittimpulsen als Reaktion auf Positions- oder Geschwindigkeitsbefehle. Im Positionsmodus verfügt sie über eine integrierte, voreingestellte Positionsschleife, so dass eine PID-Einstellung nicht erforderlich ist. Im Geschwindigkeitsmodus treibt sie einen Motor mit der befohlenen Geschwindigkeit an, wobei Geschwindigkeits- und Beschleunigungsgrenzen eingehalten werden. Es handelt sich um eine reine Echtzeitkomponente, die je nach CPU-Geschwindigkeit usw. maximale Schrittfrequenzen von 10 kHz bis vielleicht 50 kHz erreichen kann. Das Blockdiagramm des Schrittimpulsgenerators zeigt drei Blockdiagramme, jedes davon ist ein einzelner Schrittimpulsgenerator. Das erste Diagramm ist für den Schritttyp 0 (Schritt und Richtung). Das zweite ist für den Schritttyp 1 (Auf/Ab oder Pseudo-PWM), und das dritte für die Schritttypen 2 bis 14 (verschiedene Schrittmuster). Die ersten beiden Diagramme zeigen die Steuerung im Positionsmodus, das dritte den Geschwindigkeitsmodus. Steuermodus und Schrittart werden unabhängig voneinander eingestellt, und es kann jede beliebige Kombination gewählt werden.

images/stepgen-block-diag.png
Abbildung 1. Schrittimpulsgenerator-Blockdiagramm Positionsmodus
Laden der Komponente stepgen
halcmd: loadrt stepgen step_type=<type-array> [ctrl_type=<ctrl_array>]
<type-array>

ist eine Reihe von durch Kommata getrennten Dezimalzahlen. Jede Zahl bewirkt, dass ein Einzelschritt-Impulsgenerator geladen wird; der Wert der Zahl bestimmt die Schrittart.

<ctrl_array>

ist eine durch Komma getrennte Folge von p- oder v-Zeichen, um den Positions- oder Geschwindigkeitsmodus anzugeben.

ctrl_type

ist optional, wenn sie weggelassen wird, werden alle Schrittgeneratoren im Positionsmodus arbeiten.

Zum Beispiel:

halcmd: loadrt stepgen step_type=0,0,2 ctrl_type=p,p,v

Es werden drei Schrittgeneratoren installiert. Die ersten beiden verwenden den Schritttyp 0 (Schritt und Richtung) und laufen im Positionsmodus. Der letzte verwendet den Schritttyp 2 (Quadratur) und läuft im Geschwindigkeitsmodus. Der Standardwert für <config-array> ist 0,0,0, wodurch drei Generatoren vom Typ 0 (Schritt/Richtung) installiert werden. Die maximale Anzahl von Schrittgeneratoren ist 8 (wie durch MAX_CHAN in stepgen.c definiert). Jeder Generator ist unabhängig, aber alle werden durch dieselbe(n) Funktion(en) zur gleichen Zeit aktualisiert. In den folgenden Beschreibungen steht <chan> für die Nummer eines bestimmten Generators. Der erste Generator hat die Nummer 0.

Komponente "stepgen" entfernen (engl. unload)
halcmd: unloadrt stepgen

1.1. Pins

Zur gewählten Schrift- und Steuerungsart.

  • (float) stepgen.`__<chan>__.position-cmd` - Gewünschte Motorposition, in Positionseinheiten (nur Positionsmodus).

  • (float) stepgen.`__<chan>__.velocity-cmd` - Gewünschte Motorgeschwindigkeit, in Positionseinheiten pro Sekunde (nur im Geschwindigkeitsmodus).

  • (s32) stepgen.`__<chan>__.counts` - Rückmeldeposition in Zählungen, aktualisiert durch capture_position().

  • (float) stepgen.`__<chan>__.position-fb` - Feedback-Position in Positionseinheiten, aktualisiert durch capture_position().

  • (bit) stepgen.`__<chan>__.enable` - Aktiviert Ausgabeschritte - wenn false, werden keine Schritte erzeugt.

  • (bit) stepgen.`__<chan>__.step` - Schrittimpulsausgang (nur Schritttyp 0).

  • (bit) stepgen.`__<chan>__.dir` - Richtungsausgabe (nur Schritttyp 0).

  • (bit) stepgen.`__<chan>__.up` - UP Pseudo-PWM Ausgang (nur Schritttyp 1).

  • (bit) stepgen.`__<chan>__.down` - DOWN Pseudo-PWM-Ausgang (nur Schritttyp 1).

  • (bit) stepgen.`__<chan>__.phase-A` - Ausgang Phase A (nur Schritttypen 2-14).

  • (bit) stepgen.`__<chan>__.phase-B` - Ausgang Phase B (nur Schritttypen 2-14).

  • (bit) stepgen.`__<chan>__.phase-C` - Phase-C-Ausgang (nur Schritttypen 3-14).

  • (bit) stepgen.`__<chan>__.phase-D` - Phase-D-Ausgang (nur Schritttypen 5-14).

  • (bit) stepgen.`__<chan>__.phase-E` - Phase-E-Ausgang (nur Schritttypen 11-14).

1.2. Parameter

  • (float) stepgen.`__<chan>__.position-scale` - Schritte pro Positionseinheit. Dieser Parameter wird sowohl für die Ausgabe als auch für die Rückmeldung verwendet.

  • (float) stepgen.`__<chan>__.maxvel` - Maximale Geschwindigkeit, in Positionseinheiten pro Sekunde. Wenn 0.0, hat keine Auswirkung.

  • (float) stepgen.`__<chan>__.maxaccel` - Maximale Beschleunigungs-/Verzögerungsrate, in Positionseinheiten pro Sekunde zum Quadrat. Wenn 0.0, hat keine Auswirkung.

  • (float) stepgen.`__<chan>__.frequency` - Die aktuelle Schrittfrequenz in Schritten pro Sekunde.

  • (float) stepgen.`__<chan>__.steplen` - Länge eines Schrittimpulses (Schritttyp 0 und 1) oder Mindestzeit in einem bestimmten Zustand (Schritttypen 2-14), in Nanosekunden.

  • (float) stepgen.`__<chan>__.stepspace` - Mindestabstand zwischen zwei Schrittimpulsen (nur Schritttypen 0 und 1), in Nanosekunden. Wird auf 0 gesetzt, um die stepgen-Funktion doublefreq zu aktivieren. Um doublefreq zu verwenden, muss die parport Reset-Function aktiviert sein.

  • (float) stepgen.`__<chan>__.dirsetup` - Mindestzeit zwischen einem Richtungswechsel und dem Beginn des nächsten Schrittimpulses (nur Schritttyp 0), in Nanosekunden.

  • (float) stepgen.`__<chan>__.dirhold` - Mindestzeit vom Ende eines Schrittimpulses bis zu einem Richtungswechsel (nur Schritttyp 0), in Nanosekunden.

  • (float) ‚stepgen.`__<chan>__.dirdelay‘ - Mindestzeit zwischen einem Schritt und einem Schritt in die entgegengesetzte Richtung (nur Schritttypen 1-14), in Nanosekunden.

  • (s32) stepgen.`__<chan>__.rawcounts` - Die rohe Anzahl der Rückmeldungen, aktualisiert durch make_pulses().

Im Positionsmodus werden die Werte von maxvel und maxaccel von der internen Positionsschleife verwendet, um Schrittimpulsfolgen zu vermeiden, denen der Motor nicht folgen kann. Wenn sie auf Werte eingestellt sind, die für den Motor geeignet sind, führt selbst eine große momentane Änderung der befohlenen Position zu einer sanften trapezförmigen Bewegung zur neuen Position. Der Algorithmus misst sowohl den Positions- als auch den Geschwindigkeitsfehler und berechnet eine Beschleunigung, die versucht, beide gleichzeitig auf Null zu reduzieren. Weitere Einzelheiten, einschließlich des Inhalts des Feldes "Kontrollgleichung" (engl. control equation), finden Sie im Code.

Im Geschwindigkeitsmodus ist maxvel ein einfacher Grenzwert, der auf die befohlene Geschwindigkeit angewendet wird, und maxaccel wird verwendet, um die tatsächliche Frequenz zu rampen, wenn sich die befohlene Geschwindigkeit abrupt ändert. Wie im Positionsmodus sorgen die richtigen Werte für diese Parameter dafür, dass der Motor der erzeugten Impulsfolge folgen kann.

1.3. Schritttypen

Der Schrittgenerator unterstützt 15 verschiedene Schrittfolgen:

Schritttyp 0 (engl. step type 0)

Schritttyp 0 ist der Standard-Schritt- und Richtungstyp. Bei der Konfiguration für den Schritttyp 0 gibt es vier zusätzliche Parameter, die das genaue Timing der Schritt- und Richtungssignale bestimmen. In der folgenden Abbildung ist die Bedeutung dieser Parameter dargestellt. Die Parameter sind in Nanosekunden angegeben, werden aber auf ein ganzzahliges Vielfaches der Thread-Periode für den Thread aufgerundet, der make_pulses() aufruft. Wenn zum Beispiel make_pulses() alle 16 µs aufgerufen wird und steplen 20000 ist, dann sind die Schrittimpulse 2 x 16 = 32 µs lang. Der Standardwert für alle vier Parameter ist 1 ns, aber die automatische Rundung tritt in Kraft, wenn der Code zum ersten Mal ausgeführt wird. Da ein Schritt steplen ns hoch und stepspace ns niedrig benötigt, ist die maximale Frequenz 1.000.000.000 geteilt durch (steplen + stepspace)'. Wenn maxfreq höher als dieser Grenzwert eingestellt ist, wird er automatisch gesenkt. Ist maxfreq gleich Null, bleibt er Null, aber die Ausgangsfrequenz wird trotzdem begrenzt.

Bei Verwendung des Parallelport-Treibers kann die Schrittfrequenz mit der Funktion parport reset in Verbindung mit der Einstellung doublefreq von StepGen verdoppelt werden.

images/stepgen-type0.png
Abbildung 2. Schritt- und Richtungs-Timing (engl. step and direction timing)
Schritt Typ 1 (step type 1)

Der Schritttyp 1 hat zwei Ausgänge, aufwärts und abwärts. Die Impulse erscheinen je nach Fahrtrichtung an dem einen oder dem anderen. Jeder Impuls ist steplen ns lang, und die Impulse sind durch mindestens stepspace ns voneinander getrennt. Die maximale Frequenz ist dieselbe wie bei Schritttyp 0. Wenn maxfreq höher als der Grenzwert eingestellt ist, wird dieser gesenkt. Ist maxfreq gleich Null, bleibt er Null, aber die Ausgangsfrequenz wird trotzdem begrenzt.

Warnung
Verwenden Sie die Parport-Reset-Funktion nicht mit den Schritttypen 2 - 14. Unerwartete Ergebnisse können auftreten.
Schritt Typen 2 - 14 (engl. step type 2-14)

Die Schritttypen 2 bis 14 sind zustandsabhängig und haben zwei bis fünf Ausgänge. Bei jedem Schritt wird ein Zustandszähler inkrementiert oder dekrementiert. Die Zwei-und-Drei-Phasen-, Vier-Phasen- und Fünf-Phasen-Schritte zeigen die Ausgangsmuster als Funktion des Zustandszählers. Die maximale Frequenz ist 1.000.000.000 geteilt durch steplen, und wie in den anderen Modi wird maxfreq gesenkt, wenn es über dem Grenzwert liegt.

Schritttypen: Zwei-und-Drei-Phase
Abbildung 3. Zwei- und dreiphasige Schritttypen
Schritttypen: Vierphasig
Abbildung 4. Vierphasige Schritttypen
Schritttypen: Fünfphasig
Abbildung 5. Fünf-Phasen-Schritttypen

1.4. Funktionen

Die Komponente exportiert drei Funktionen. Jede Funktion wirkt auf alle Schrittimpulsgeneratoren - die Ausführung verschiedener Generatoren in verschiedenen Threads wird nicht unterstützt.

  • (funct) stepgen.make-pulses - Hochgeschwindigkeitsfunktion zum Erzeugen und Zählen von Impulsen (kein Fließkomma).

  • (funct) stepgen.update-freq - Die Funktion für niedrige Geschwindigkeiten wandelt Position in Geschwindigkeit um, skaliert und begrenzt.

  • (funct) stepgen.capture-position - Funktion mit niedriger Geschwindigkeit für die Rückmeldung, aktualisiert die Zwischenspeicher und skaliert die Position.

Die Hochgeschwindigkeitsfunktion stepgen.make-pulses sollte in einem sehr schnellen Thread ausgeführt werden, je nach den Fähigkeiten des Computers zwischen 10 und 50 µs. Die Periode dieses Threads bestimmt die maximale Schrittfrequenz, da steplen, stepspace, dirsetup, dirhold und dirdelay alle auf ein ganzzahliges Vielfaches der Thread-Periode in Nanosekunden aufgerundet werden. Die beiden anderen Funktionen können mit einer viel geringeren Rate aufgerufen werden.

2. PWMgen

Diese Komponente ermöglicht die softwarebasierte Erzeugung von PWM- (Pulse Width Modulation) und PDM- (Pulse Density Modulation) Wellenformen. Es handelt sich um eine reine Echtzeitkomponente, die je nach CPU-Geschwindigkeit usw. PWM-Frequenzen von einigen hundert Hertz bei ziemlich guter Auflösung bis zu vielleicht 10 kHz mit begrenzter Auflösung erzeugen kann.

Laden von PWMgen
loadrt pwmgen output_type=<config-array>

Das <config-array> ist eine Reihe von durch Komma getrennten Dezimalzahlen. Jede Zahl bewirkt, dass ein einzelner PWM-Generator geladen wird; der Wert der Zahl bestimmt den Ausgangstyp. Im folgenden Beispiel werden drei PWM-Generatoren installiert. Es gibt keinen Standardwert, wenn <config-array> nicht angegeben wird, werden keine PWM-Generatoren installiert. Die maximale Anzahl von Frequenzgeneratoren ist 8 (wie durch MAX_CHAN in pwmgen.c definiert). Jeder Generator ist unabhängig, aber alle werden durch dieselbe(n) Funktion(en) zur gleichen Zeit aktualisiert. In den folgenden Beschreibungen steht <chan> für die Nummer eines bestimmten Generators. Der erste Generator hat die Nummer 0.

Beispiel für das Laden von PWMgen
loadrt pwmgen output_type=0,1,2

Es werden drei PWM-Generatoren installiert. Der erste wird einen Ausgang des Typs 0 (nur PWM) verwenden, der nächste einen Ausgang des Typs 1 (PWM und Richtung) und der dritte einen Ausgang des Typs 2 (AUF und AB). Es gibt keinen Standardwert, wenn <config-array> nicht angegeben wird, wird kein PWM-Generator installiert. Die maximale Anzahl von Frequenzgeneratoren ist 8 (wie durch MAX_CHAN in pwmgen.c definiert). Jeder Generator ist unabhängig, aber alle werden durch dieselbe(n) Funktion(en) zur gleichen Zeit aktualisiert. In den folgenden Beschreibungen steht <chan> für die Anzahl der einzelnen Generatoren. Die Nummerierung der PWM-Generatoren beginnt bei 0.

Entfernen (engl. hier unloading) von PWMgen
unloadrt pwmgen

2.1. Ausgangstypen (engl. output types)

Der PWM-Generator unterstützt drei verschiedene "Ausgangstypen".

  • Ausgangstyp 0 - Nur PWM-Ausgangspin. Nur positive Befehle werden akzeptiert, negative Werte werden als Null behandelt (und werden durch den Parameter min-dc beeinflusst, wenn er ungleich Null ist).

  • Ausgangstyp 1 - PWM/PDM und Richtungspins. Positive und negative Inputs werden als positive und negative PWM ausgegeben. Der Richtungspin ist false für positive Befehle und true für negative Befehle. Wenn Ihre Steuerung positive PWM sowohl für CW als auch für CCW benötigt, verwenden Sie den Link:.. /man/man9/abs.9.html[abs]-Komponente, um Ihr PWM-Signal in einen positiven Wert umzuwandeln, wenn ein negativer Eingang eingegeben wird.

  • Ausgabetyp 2 - UP- und DOWN-Pins. Bei positiven Befehlen wird das PWM-Signal am Up-Ausgang angezeigt, und der Down-Ausgang bleibt false. Bei negativen Befehlen wird das PWM-Signal am Down-Ausgang angezeigt, und der Up-Ausgang bleibt false. Der Ausgangstyp 2 eignet sich für den Antrieb der meisten H-Brücken.

2.2. Pins

Jeder PWM-Generator hat die folgenden Pins:

  • (float) pwmgen.`__<chan>__.value` - Befehlswert, in beliebigen Einheiten. Wird durch den Parameter scale skaliert (siehe unten).

  • (bit) pwmgen.`__<chan>__.enable` - Aktiviert oder deaktiviert die PWM-Generatorausgänge.

Jeder PWM-Generator verfügt über einige dieser Pins, je nach gewähltem Ausgangstyp:

  • (bit) pwmgen.`__<chan>__.pwm` - PWM- (oder PDM-) Ausgang, (nur Ausgangstyp 0 und 1).

  • (bit) pwmgen.`__<chan>__.dir` - Richtungsausgabe (nur Ausgabetyp 1).

  • (bit) pwmgen.`__<chan>__.up` - PWM/PDM-Ausgang für positiven Eingangswert (nur Ausgangstyp 2).

  • (bit) pwmgen.`__<chan>__.down` - PWM/PDM-Ausgang für negativen Eingangswert (nur Ausgangstyp 2).

2.3. Parameter

  • (float) pwmgen.`__<chan>__.scale` - Skalierungsfaktor zur Konvertierung von value von beliebigen Einheiten in Duty Cycle. Wenn z.B. scale auf 4000 gesetzt ist und der Eingangswert, der an pwmgen.`__<chan>__.value` übergeben wird, 4000 ist, dann wird es 100% Duty-Cycle (immer an) sein. Beträgt der Wert 2000, so handelt es sich um eine 50%ige 25 Hz-Rechteckwelle.

  • (float) ‚pwmgen.`__<chan>__.pwm-freq - Gewünschte PWM-Frequenz, in Hz. Wenn 0.0, wird PDM statt PWM erzeugt. Ist die Frequenz höher als die internen Grenzwerte, wird sie beim nächsten Aufruf von update_freq()‘ auf den internen Grenzwert gesetzt. Falls ungleich Null und dither falsch, wird der nächste Aufruf von update_freq() auf das nächste ganzzahlige Vielfache der Periode der Funktion make_pulses() gesetzt.

  • (bit) pwmgen.`__<chan>__.dither-pwm` - Bei true wird Dithering aktiviert, um durchschnittliche PWM-Frequenzen oder Tastverhältnisse zu erreichen, die mit reiner PWM nicht möglich sind. Bei false werden sowohl die PWM-Frequenz als auch das Tastverhältnis auf Werte gerundet, die genau erreicht werden können.

  • (float) pwmgen.`__<chan>__.min-dc` - Minimales Tastverhältnis, zwischen 0,0 und 1,0 (das Tastverhältnis geht unabhängig von dieser Einstellung auf Null, wenn es deaktiviert wird).

  • (float) pwmgen.`__<chan>__.max-dc` - Maximales Tastverhältnis, zwischen 0,0 und 1,0.

  • (float) pwmgen.`__<chan>__.curr-dc` - Aktuelles Tastverhältnis - nach allen Begrenzungen und Rundungen (nur Lesen).

2.4. Funktionen

Die Komponente exportiert zwei Funktionen. Jede Funktion wirkt auf alle PWM-Generatoren - die Ausführung verschiedener Generatoren in verschiedenen Threads wird nicht unterstützt.

  • (funct) pwmgen.make-pulses - Hochgeschwindigkeitsfunktion zur Erzeugung von PWM-Wellenformen (keine Fließkommazahlen). Die Hochgeschwindigkeitsfunktion pwmgen.make-pulses sollte im Basis-Thread (schnellster Thread) ausgeführt werden, je nach den Fähigkeiten des Computers zwischen 10 und 50 µs. Die Periode dieses Threads bestimmt die maximale PWM-Trägerfrequenz sowie die Auflösung der PWM- oder PDM-Signale. Wenn der Basis-Thread 50.000 ns beträgt, entscheidet das Modul alle 50 µs, ob es an der Zeit ist, den Zustand des Ausgangs zu ändern. Bei einem Tastverhältnis von 50 % und einer PWM-Frequenz von 25 Hz bedeutet dies, dass sich der Zustand des Ausgangs alle (1 / 25) Sekunden / 50 µs * 50 % = 400 Iterationen ändert. Das bedeutet auch, dass Sie 800 mögliche Tastverhältniswerte haben (ohne Dithering).

  • (funct) pwmgen.update - Funktion mit geringer Geschwindigkeit zur Skalierung und Begrenzung des Werts und zur Handhabung anderer Parameter. Dies ist die Funktion des Moduls, welche die komplizierteren mathematischen Berechnungen implementiert, um herauszufinden, für wie viele Basisperioden der Ausgang hoch und für wie viele er niedrig sein sollte.

3. Encoder

Diese Komponente ermöglicht die softwarebasierte Zählung von Signalen aus Quadratur- (oder Einzelimpuls-) Encodern. Es handelt sich um eine reine Echtzeitkomponente, die je nach CPU-Geschwindigkeit, Latenzzeit usw. maximale Zählraten von 10 kHz bis vielleicht 50 kHz erreichen kann.

Das Basisgewinde sollte 1/2 Zählgeschwindigkeit betragen, um Geräusche und Zeitschwankungen zu berücksichtigen. Wenn Sie z. B. einen Drehgeber mit 100 Impulsen pro Umdrehung an der Spindel haben und Ihre maximale Drehzahl 3000 beträgt, sollte das maximale Basisgewinde 25 µs betragen. Ein Drehgeber mit 100 Impulsen pro Umdrehung hat 400 Zählungen. Die Spindeldrehzahl von 3000 U/min (engl. RPM) = 50 U/s (engl. RPS, Umdrehungen pro Sekunde). 400 * 50 = 20.000 Zählungen pro Sekunde oder 50 µs zwischen den Zählungen.

Das Blockdiagramm des Encoderzählers ist ein Blockdiagramm eines Kanals eines Encoderzählers.

images/encoder-block-diag.png
Abbildung 6. Encoderzähler-Blockdiagramm
Laden des Encoders
halcmd: loadrt encoder [num_chan=<counters>]

<counters> ist die Anzahl der Encoderzähler, die Sie installieren möchten. Wenn num_chan nicht angegeben ist, werden drei Zähler installiert. Die maximale Anzahl von Leistungsindikatoren beträgt 8 (wie durch MAX_CHAN in encoder.c definiert). Jeder Leistungsindikator ist unabhängig, aber alle werden gleichzeitig von den gleichen Funktionen aktualisiert. In den folgenden Beschreibungen ist <chan> die Nummer eines bestimmten Zählers. Der erste Zähler ist die Nummer 0.

Encoder entfernen (engl. unload)
halcmd: unloadrt encoder

3.1. Pins

  • encoder._<chan>_.counter-mode (bit, I/O) (Voreinstellung: FALSE) - Aktiviert den Zählermodus. Bei true zählt der Zähler jede steigende Flanke des Phase-A-Eingangs und ignoriert den Wert an Phase-B. Dies ist nützlich, um den Ausgang eines einkanaligen (nicht-Quadratur-) Sensors zu zählen. Bei false zählt er im Quadraturmodus.

  • encoder._<chan>_.missing-teeth (s32, In) (Voreinstellung: 0) - Aktiviert die Verwendung des Fehlzahn-Index. Dadurch kann ein einzelner IO-Pin sowohl Positions- als auch Indexinformationen liefern. Wenn das Geberrad 58 Zähne hat, von denen zwei fehlen, die so angeordnet sind, als wären es 60 (wie bei Kurbelwellensensoren in der Automobilindustrie üblich), dann sollte die Positionsskala auf 60 und die fehlenden Zähne auf 2 gesetzt werden. Um diesen Modus zu verwenden, sollte counter-mode auf true gesetzt werden. Dieser Modus eignet sich zum Gewindedrehen, aber nicht zum Gewindeschneiden.

  • encoder._<chan>_.counts (s32, Out) - Position in encoder Zählungen (engl. counts).

  • encoder._<chan>_.counts-latched (s32, Out) - Zur Zeit nicht verwendet.

  • encoder._<chan>_.index-enable (bit, I/O) - Wenn True, werden counts und position bei der nächsten steigenden Flanke von Phase Z auf Null zurückgesetzt.
    Gleichzeitig wird index-enable auf Null zurückgesetzt, um anzuzeigen, dass die steigende Flanke aufgetreten ist. Der index-enable-Pin ist bidirektional. Wenn index-enable False ist, wird der Phase-Z-Kanal des Encoders ignoriert und der Zähler zählt normal. Der Encoder-Treiber wird index-enable niemals auf True setzen. Einige andere Komponenten können dies jedoch tun.

  • encoder._<chan>_.latch-falling (bit, In) (Standard: TRUE) - Derzeit nicht verwendet.

  • encoder._<chan>_.latch-input (bit, In) (Voreinstellung: TRUE) - Zur Zeit nicht verwendet.

  • encoder._<chan>_.latch-rising (bit, In) - Derzeit nicht verwendet.

  • encoder._<chan>_.min-speed-estimate (float, in) - Bestimmt die minimale wahre Geschwindigkeitsgröße, bei der die Geschwindigkeit als ungleich Null geschätzt und die Position interpoliert wird. Die Einheiten von min-speed-estimate sind die gleichen wie die Einheiten von velocity . Skalierungsfaktor, in Zählungen pro Längeneinheit. Wird dieser Parameter zu niedrig eingestellt, dauert es sehr lange, bis die Geschwindigkeit auf 0 zurückgeht, nachdem keine Geberimpulse mehr ankommen.

  • encoder._<chan>_.phase-A (bit, In) - Phase A des Quadratur Encoder Signals.

  • encoder._<chan>_.phase-B (bit, In) - Phase B des Quadratur Encoder Signals.

  • encoder._<chan>_.phase-Z (Bit, In) - Phase Z (Indeximpuls) des Quadratur-Encodersignals.

  • encoder._<chan>_.position (float, Out) - Position in skalierten Einheiten (siehe position-scale).

  • encoder._<chan>_.position-interpolated (float, Out) - Position in skalierten Einheiten, interpoliert zwischen Encoder-Zählungen.
    Die position-interpolated versucht, zwischen den Encoderzählungen zu interpolieren, basierend auf der zuletzt gemessenen Geschwindigkeit. Nur gültig, wenn die Geschwindigkeit annähernd konstant ist und über der min-speed-estimate liegt. Nicht für die Lageregelung verwenden, da der Wert bei niedrigen Geschwindigkeiten, bei Richtungsumkehr und bei Geschwindigkeitsänderungen falsch ist.
    Er ermöglicht jedoch die Verwendung eines Encoders mit niedrigem Impuls pro Umdrehung (einschließlich eines Encoders mit einem Impuls pro Umdrehung) für das Gewindeschneiden auf einer Drehmaschine und kann auch für andere Zwecke verwendet werden.

  • encoder._<chan>_.position-latched (float, Out) - Wird derzeit nicht verwendet.

  • encoder._<chan>_.position-scale (float, I/O) – Skalierungsfaktor, in Zählungen pro Längeneinheit. Wenn beispielsweise die Positionsskala 500 beträgt, werden 1000 Zählwerte des Encoders als Position von 2.0 Einheiten gemeldet.

  • encoder._<chan>_.rawcounts (s32, In) - Die rohe Anzahl, wie durch Update-Zähler bestimmt. Dieser Wert wird häufiger aktualisiert als Anzahl und Position. Es ist auch unbeeinflusst von Reset oder dem Indeximpuls.

  • encoder._<chan>_.reset (bit, In) - Wenn True, werden counts und position sofort auf Null gesetzt.

  • encoder._<chan>_.velocity (float, Out) - Geschwindigkeit in skalierten Einheiten pro Sekunde. encoder verwendet einen Algorithmus, der das Quantisierungsrauschen im Vergleich zur einfachen Differenzierung des position-Ausgangs stark reduziert. Wenn der Wert der tatsächlichen Geschwindigkeit unter der geschätzten Mindestgeschwindigkeit liegt, ist die Geschwindigkeitsausgabe 0.

  • encoder._<chan>_.x4-mode (bit, I/O) (Voreinstellung: TRUE) - Aktiviert den Times-4-Modus. Bei true zählt der Zähler jede Flanke der Quadraturwellenform (vier Zählungen pro vollem Zyklus). Bei false zählt er nur einmal pro vollem Zyklus. Im Zählermodus wird dieser Parameter ignoriert. Der 1x-Modus ist für einige Jogwheels nützlich.

3.2. Parameter

  • encoder._<chan>_.capture-position.time (s32, RO)

  • encoder._<chan>_.capture-position.tmax (s32, RW)

  • encoder._<chan>_.update-counters.time (s32, RO)

  • encoder._<chan>_.update-counter.tmax (s32, RW)

3.3. Funktionen

Die Komponente exportiert zwei Funktionen. Jede Funktion wirkt auf alle Zähler des Encoders - die Ausführung verschiedener Zähler in verschiedenen Threads wird nicht unterstützt.

  • (funct) encoder.update-counters - Hochgeschwindigkeitsfunktion zum Zählen von Impulsen (kein Gleitkomma).

  • (funct) encoder.capture-position - Funktion mit niedriger Geschwindigkeit zur Aktualisierung von Latches und Skalenposition.

4. PID

Diese Komponente bietet Proportional/Integral/Derivativ-Regelkreise. Es handelt sich um eine reine Echtzeitkomponente. Der Einfachheit halber wird in dieser Diskussion davon ausgegangen, dass es sich um Positionsregelkreise handelt. Diese Komponente kann jedoch auch zur Implementierung anderer Rückkopplungsschleifen wie Geschwindigkeit, Brennerhöhe, Temperatur usw. verwendet werden. Das Blockdiagramm der PID-Schleife ist ein Blockdiagramm einer einzelnen PID-Schleife.

images/pid-block-diag.png
Abbildung 7. PID-Regelkreis-Blockdiagramm
PID laden
halcmd: loadrt pid [num_chan=<loops>] [debug=1]

<Schleifen> ist die Anzahl der PID-Schleifen, die Sie installieren möchten. Wird num_chan nicht angegeben, so wird eine Schleife installiert. Die maximale Anzahl von Schleifen ist 16 (wie durch MAX_CHAN in pid.c definiert). Jede Schleife ist völlig unabhängig. In den folgenden Beschreibungen ist <Schleifennummer> die Schleifennummer einer bestimmten Schleife. Die erste Schleife hat die Nummer 0.

Wenn debug=1 angegeben ist, exportiert die Komponente einige zusätzliche Pins, die bei der Fehlersuche und beim Tuning nützlich sein können. Standardmäßig werden die zusätzlichen Pins nicht exportiert, um gemeinsamen Speicherplatz zu sparen und die Pin-Liste nicht zu überfrachten.

PID entfernen (engl. unload)
halcmd: unloadrt pid

4.1. Pins

Die drei wichtigsten Pins sind

  • (float) pid.`__<loopnum>__.command` - Die gewünschte Position, wie sie von einer anderen Systemkomponente befohlen wurde.

  • (float) pid.`__<Schleifennummer>__.feedback` - Die aktuelle Position, wie sie von einem Rückmeldegerät wie einem Encoder gemessen wird.

  • (float) pid.`__<loopnum>__.output` - Ein Geschwindigkeitsbefehl, der versucht, von der aktuellen Position zur gewünschten Position zu gelangen.

Bei einer Positionsschleife sind .command (engl. für Befehl) und .feedback (engl. für Rückmeldung) in Positionseinheiten angegeben. Bei einer linearen Achse können dies Zoll, mm, Meter oder andere relevante Einheiten sein. Bei einer Winkelachse kann es sich um Grad, Bogenmaß usw. handeln. Die Einheiten des .output Ausgangspins entsprechen der Änderung, die erforderlich ist, damit die Rückmeldung mit dem Befehl übereinstimmt. Bei einer Positionsschleife ist der "Ausgang" eine Geschwindigkeit in Zoll/Sekunde, mm/Sekunde, Grad/Sekunde usw. Zeiteinheiten sind immer Sekunden, und die Geschwindigkeitseinheiten entsprechen den Positionseinheiten. Wenn Befehl und Rückmeldung in Metern angegeben sind, erfolgt die Ausgabe in Metern pro Sekunde.

Jede Schleife hat zwei Pins, die zur Überwachung oder Steuerung des allgemeinen Betriebs der Komponente dienen.

  • (float) pid.<Schleifennummer>.error - Entspricht .command (gefordert) minus '.feedback (Rückmeldung zu ist-Zustand).

  • (bit) pid.<loopnum>.enable - Ein Bit, das die Schleife aktiviert. Wenn .enable falsch ist, werden alle Integratoren zurückgesetzt und der Ausgang wird auf Null gezwungen. Wenn .enable wahr ist, arbeitet die Schleife normal.

Pins zur Meldung der Sättigung. Eine Sättigung ist gegeben, wenn der Ausgang des PID-Blocks an seinem maximalen oder minimalen Grenzwert liegt.

  • (Bit) pid. <loopnum>.gesättigt - True, wenn die Ausgabe gesättigt ist.

  • (float) pid.<loopnum>.saturated_s – Die Zeit, zu der die Ausgabe zuerst gesättigt war.

  • (s32) pid. <loopnum>.saturated_count - Die Dauer, seit der die Ausgabe gesättigt ist.

Die PID-Verstärkungen, Grenzwerte und andere "abstimmbare" Merkmale des Regelkreises sind als Pins verfügbar, so dass sie dynamisch für erweiterte Abstimmungsmöglichkeiten angepasst werden können.

  • (float) pid.<loopnum>.Pgain - Proportionale Verstärkung

  • (float) pid.<loopnum>.Igain - Integrale Verstärkung

  • (float) pid.<loopnum>.Dgain - Abgeleitete (engl. derivative) Verstärkung

  • (float) pid.<loopnum>.bias - Konstanter Offset (engl. bias) am Ausgang

  • (float) pid. <loopnum>. FF0 - Feedforward nullter Ordnung - Ausgabe proportional zum Befehl (Position).

  • (float) pid. <loopnum>. FF1 - Feedforward erster Ordnung - Ausgabe proportional zur Ableitung des Befehls (Geschwindigkeit).

  • (float) pid. <loopnum>. FF2 - Feedforward zweiter Ordnung - Ausgabe proportional zur 2. Ableitung des Befehls (Beschleunigung).

  • (float) pid.<loopnum>.deadband - Betrag des Fehlers, der ignoriert wird

  • (float) pid. <loopnum>.maxerror - Fehlerbegrenzung

  • (float) pid. <loopnum>.maxerrorI - Limit für Fehlerintegrator

  • (float) pid. <loopnum>.maxerrorD - Limit für Fehlerableitung

  • (float) pid.<loopnum>.maxcmdD - Begrenzung der Befehlsableitung

  • (float) pid.<loopnum>.maxcmdDD - Begrenzung der 2. Ableitung des Befehls

  • (float) pid. <loopnum>.maxoutput - Grenzwert für Ausgangswert

Alle max*-Grenzwerte sind so implementiert, dass es keinen Grenzwert gibt, wenn der Wert dieses Parameters Null ist.

Wenn bei der Installation der Komponente debug=1 angegeben wurde, werden vier zusätzliche Pins exportiert:

  • (float) pid.<loopnum>.errorI - Integral des Fehlers.

  • (float) pid.<loopnum>.errorD - Ableitung von error.

  • (float) pid. <loopnum>.commandD - Ableitung des Befehls.

  • (float) pid. <loopnum>.commandDD - 2. Ableitung des Befehls.

4.2. Funktionen

Die Komponente exportiert eine Funktion für jede PID-Schleife. Diese Funktion führt alle für die Schleife erforderlichen Berechnungen durch. Da jede Schleife ihre eigene Funktion hat, können einzelne Schleifen in verschiedene Threads eingebunden werden und mit unterschiedlichen Geschwindigkeiten ausgeführt werden.

  • (funct) pid.<loopnum>.do_pid_calcs - Führt alle Berechnungen für eine einzelne PID-Schleife durch.

Wenn Sie den genauen Algorithmus zur Berechnung des Ausgangs der PID-Schleife verstehen möchten, lesen Sie bitte

  • Abbildung PID Loop Block Diagram,

  • die Kommentare am Anfang von emc2/src/hal/components/pid.c, und natürlich auf

  • der G-Code selbst.

Die Schleifenberechnungen erfolgen in der C-Funktion „calc_pid()“.

5. Simulierter Encoder

Der simulierte Encoder ist genau das. Er erzeugt Quadraturimpulse mit einem Indeximpuls, und zwar mit einer durch einen HAL-Pin gesteuerten Geschwindigkeit. Er ist vor allem für Tests nützlich.

Sim-Encoder laden
halcmd: loadrt sim-encoder num_chan=<number>

<number> ist die Anzahl der Encoder, die Sie simulieren möchten. Wenn nicht angegeben, wird ein Encoder installiert. Die maximale Anzahl ist 8 (wie durch MAX_CHAN in sim_encoder.c definiert).

Abladen des sim-encoder
halcmd: unloadrt sim-encoder

5.1. Pins

  • (float) sim-encoder.`__<chan-num>__.speed` - Der Geschwindigkeitsbefehl für die simulierte Welle.

  • (bit) ‚sim-encoder.`__<chan-num>__`.phase-A‘ - Quadraturausgang.

  • (bit) sim-encoder.`__<chan-num>__.phase-B` - Quadraturausgang.

  • (bit) sim-encoder.`__<chan-num>__.phase-Z` - Index-Impulsausgang.

Wenn .speed positiv ist, liegt .phase-A vor .phase-B.

5.2. Parameter

  • (u32) sim-encoder.`__<chan-num>__.ppr` - Impulse pro Umdrehung.

  • (float) sim-encoder.`__<chan-num>__.scale` - Skalierungsfaktor für .speed (engl. für Geschwindigkeit). Der Standardwert ist 1.0, was bedeutet, dass die Geschwindigkeit in Umdrehungen pro Sekunde angegeben wird. Ändern Sie den Wert auf 60 für Umdrehungen pro Minute, auf 360 für Grad pro Sekunde, 6,283185 (= 2*π) für Bogenmaß pro Sekunde usw.

Beachten Sie, dass Impulse pro Umdrehung nicht dasselbe sind wie Zählungen pro Umdrehung. Ein Impuls ist ein vollständiger Quadraturzyklus. Die meisten Drehgeberzähler zählen viermal während eines vollständigen Zyklus.

5.3. Funktionen

Die Komponente exportiert zwei Funktionen. Jede Funktion wirkt auf alle simulierten Geber.

  • (funct) sim-encoder.make-pulses - Hochgeschwindigkeitsfunktion zur Erzeugung von Quadraturimpulsen (kein Fließkomma).

  • (funct) sim-encoder.update-speed - Funktion für niedrige Geschwindigkeit zum Lesen von .speed, Skalieren und Einrichten von .make-pulses.

6. Entprellung (engl. debounce)

Die Entprellung ist eine Echtzeitkomponente, zum Herausfiltern der durch mechanische Schaltkontakte verursachten Störungen. Sie kann auch in anderen Anwendungen nützlich sein, in denen kurze Impulse unterdrückt werden müssen.

Debounce wird geladen
halcmd: loadrt debounce cfg=<config-string>
<Konfigurations-Zeichenfolge>

Ist eine Reihe von durch Komma getrennten Dezimalzahlen. Jede Zahl installiert eine Gruppe identischer Entprellungsfilter, wobei die Zahl angibt, wie viele Filter in der Gruppe enthalten sind.

Beispiel zum Laden von Debounce
halcmd: loadrt debounce cfg=1,4,2

werden drei Gruppen von Filtern installiert. Gruppe 0 enthält einen Filter, Gruppe 1 enthält vier Filter und Gruppe 2 enthält zwei Filter. Der Standardwert für <config-string> ist "1", wodurch eine einzige Gruppe mit einem einzigen Filter installiert wird. Die maximale Anzahl von Gruppen ist 8 (wie durch MAX_GROUPS in debounce.c definiert). Die maximale Anzahl von Filtern in einer Gruppe ist nur durch den gemeinsamen Speicherplatz begrenzt. Jede Gruppe ist völlig unabhängig. Alle Filter in einer Gruppe sind identisch und werden alle von derselben Funktion gleichzeitig aktualisiert. In den folgenden Beschreibungen steht <G> für die Gruppennummer und <F> für die Filternummer innerhalb der Gruppe. Der erste Filter ist Gruppe 0, Filter 0.

Entladen der Entprellung
halcmd: unloadrt debounce

6.1. Pins

Jeder einzelne Filter hat zwei Pins.

  • (bit) debounce.`__<G>__.__<F>__.in` - Eingang von Filter <F> in Gruppe <G>.

  • (bit) debounce.`__<G>__.__<F>__.out` - Ausgang von Filter <F> in Gruppe <G>.

6.2. Parameter

Jede Gruppe von Filtern hat einen ParameterFußnote:[Jeder einzelne Filter hat auch eine interne Statusvariable. Es gibt einen Kompilierzeitschalter, der diese Variable als Parameter exportieren kann. Dies ist für Tests gedacht und verschwendet unter normalen Umständen nur gemeinsamen Speicher.].

  • (s32) debounce.`__<G>__.delay` - Filterverzögerung für alle Filter in der Gruppe <G>.

Die Filter-Verzögerung (engl. delay) wird in Einheiten von Thread-Perioden angegeben. Die minimale Verzögerung ist Null. Der Ausgang eines Filters mit einer Verzögerung von Null folgt genau seinem Eingang - er filtert nichts. Mit zunehmendem .delay werden immer längere Störimpulse zurückgewiesen. Wenn .delay 4 ist, werden alle Störungen zurückgewiesen, die kleiner oder gleich vier Thread-Perioden sind.

6.3. Funktionen

Jede Gruppe von Filtern hat eine Funktion, die alle Filter in dieser Gruppe "gleichzeitig" aktualisiert. Verschiedene Gruppen von Filtern können von verschiedenen Threads in verschiedenen Zeiträumen aktualisiert werden.

  • (funct) debounce.<G> - Aktualisiert alle Filter in der Gruppe <G>.

7. SigGen

SigGen ist eine Echtzeitkomponente, die Rechteck-, Dreieck- und Sinuswellen erzeugt. Sie wird hauptsächlich zum Testen verwendet.

Laden von siggen
halcmd: loadrt siggen [num_chan=<chans>]
<chans>

ist die Anzahl der Signalgeber, die Sie installieren möchten. Wenn numchan nicht angegeben wird, dann wird ein Signalgenerator installiert. Die maximale Anzahl von Generatoren ist 16 (wie durch MAX_CHAN in siggen.c definiert). Jeder Generator ist völlig unabhängig. In den folgenden Beschreibungen ist

<chan>

die Nummer eines bestimmten Signalgebers (die Nummern beginnen bei 0).

Entladen (engl. unload) von Siggen
halcmd: unloadrt siggen

7.1. Pins

Jeder Generator hat fünf Ausgangspins.

  • (float) siggen.`__<chan>__.sine` - Ausgabe einer Sinuswelle.

  • (float) siggen.`__<chan>__.cosine` - Ausgabe eines Kosinus.

  • (float) siggen.`__<chan>__.sawtooth` - Sägezahn-Ausgang.

  • (float) siggen.`__<chan>__.triangle` - Ausgabe einer Dreieckswelle.

  • (float) siggen.`__<chan>__.square` - Ausgabe von Rechteckwellen.

Alle fünf Ausgänge haben die gleiche Frequenz, Amplitude und Offset.

Zusätzlich zu den Ausgangspins gibt es drei Steuerpins:

  • (float) siggen.`__<chan>__.frequency` - Legt die Frequenz in Hertz fest, Standardwert ist 1 Hz.

  • (float) siggen.`__<chan>__.amplitude` - Legt die Spitzenamplitude der Ausgangswellenformen fest, Standardwert ist 1.

  • (float) siggen.`__<chan>__.offset` - Setzt den DC-Offset der Ausgangswellenformen, der Standardwert ist 0.

Wenn zum Beispiel siggen.0.amplitude 1,0 und siggen.0.offset 0,0 ist, schwanken die Ausgänge von -1,0 bis +1,0. Wenn siggen.0.amplitude 2,5 und siggen.0.offset 10,0 ist, schwanken die Ausgänge zwischen 7,5 und 12,5.

7.2. Parameter

Keine.
[Vor Version 2.1 waren Frequenz, Amplitude und Offset Parameter. Sie wurden in Pins geändert, um die Steuerung durch andere Komponenten zu ermöglichen.]

7.3. Funktionen

  • (funct) siggen.`__<chan>__.update` - Berechnet neue Werte für alle fünf Ausgaben.

8. lut5

Die Komponente lut5 ist eine Logikkomponente mit 5 Eingängen, die auf einer Look-up-Tabelle basiert.

  • lut5 benötigt keinen Fließkomma-Thread.

Laden von lut5
loadrt lut5 [count=N|names=name1[,name2...]]
addf lut5.N servo-thread | base-thread
setp lut5.N.function 0xN
lut5-Rechenfunktion

Um die hexadezimale Zahl für die Funktion zu berechnen, fangen Sie oben an und schreiben Sie eine 1 oder 0, um anzugeben, ob diese Zeile wahr oder falsch ist. Als Nächstes notieren Sie jede Zahl in der Ausgabespalte, beginnend von oben und von rechts nach links. Dies wird die Binärzahl sein. Mit einem Taschenrechner mit einer Programmansicht wie der in Ubuntu geben Sie die Binärzahl ein und konvertieren sie dann in Hexadezimal und das ist dann der Wert für die Funktion.

Tabelle 1. lut5 Look Up Table
Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Ausgabe

0

0

0

0

0

0

0

0

0

1

0

0

0

1

0

0

0

0

1

1

0

0

1

0

0

0

0

1

0

1

0

0

1

1

0

0

0

1

1

1

0

1

0

0

0

0

1

0

0

1

0

1

0

1

0

0

1

0

1

1

0

1

1

0

0

0

1

1

0

1

0

1

1

1

0

0

1

1

1

1

1

0

0

0

0

1

0

0

0

1

1

0

0

1

0

1

0

0

1

1

1

0

1

0

0

1

0

1

0

1

1

0

1

1

0

1

0

1

1

1

1

1

0

0

0

1

1

0

0

1

1

1

0

1

0

1

1

0

1

1

1

1

1

0

0

1

1

1

0

1

1

1

1

1

0

1

1

1

1

1

lut5 Zwei Eingänge Beispiel

In der folgenden Tabelle haben wir für jede Zeile den Ausgangszustand ausgewählt, den wir für wahr halten wollen.

Tabelle 2. lut5 Zwei Eingänge Beispiel Look Up Table
Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Ausgabe

0

0

0

0

0

0

0

0

0

0

1

1

0

0

0

1

0

0

0

0

0

1

1

1

In der Ausgangsspalte unseres Beispiels soll der Ausgang eingeschaltet sein, wenn Bit 0 oder Bit 0 und Bit1 eingeschaltet sind und sonst nichts. Die binäre Zahl ist b1010 (drehen Sie den Ausgang um 90 Grad nach rechts). Geben Sie diese Zahl in den Taschenrechner ein und stellen Sie die Anzeige auf hexadezimal um. Das hexadezimale Präfix ist 0x.