ShuttleXpress Handwheel (de_DE) - PeterMue/ZX45-LinuxCNC GitHub Wiki
Ich habe mir vor kurzem einen ShuttleXpress Multimedia Controller gekauft, um ihn als Handrad für meine ZX45 zu verwenden.
Nachdem das Teil echt geschmeidig funktioniert und noch dazu eine recht kostengünstige Möglichkeit für ein Handrad ist, möchte ich euch das nicht vorenthalten. Im Internet findet man leider relativ wenig dazu, weswegen ich hier ein How-To dazu schreiben möchte.
Ich habe auch ein YouTube Video gemacht, in dem ich kurz Zeige und Erkläre wie das Teil funktioniert: http://www.youtube.com/watch?v=33z7xY4Rq2A
ShuttleXpress in LinuxCNC
Voraussetzungen
- CNC Maschine mit LinuxCNC
- ShuttleXpress
- Grundlegendes Verständnis der LinuxCNC HAL Konfiguration (ich versuche alles step-by-step zu erklären)
ShuttleXpress
Das ShuttleXpress ist ein "Mutlimedia Controller" von Contour Design und eigentlich wohl für soetwas wie Musik- oder Videoschnitt gedacht. Preislich liegt das Teil neu bei ~50€ und kann bei den üblichen verdächtigen gekauft werden; bspw. Amazon: https://amzn.to/2LmRYhr
Das Gerät hat in der Mitte zwei unabhängige "Räder", wovon das innere eine 10 Punkte Rastung hat und "unendlich" gedreht werden kann, das äußere ist der sog. "Shuttle-Ring" und kann ca 85° nach links und rechts gedreht werden. Wird der Ring losgelassen springt er aber wieder zurück auf die Ausgangsposition (0°). Außerdem hat das Teil noch fünf Buttons, die in einem Halbkreis um das Zentrum angeordnet sind.
Das Teil wird im übrigen auch als umgelabelte Variante von Tormach als Zubehör für ihre PCNC Fräsmaschinen verkauft. Nachdem PathPilot - die Steuerung von Tormach - auch auf LinuxCNC basiert, handelt es sich vmtl. um 1:1 das selbe Teil.
Funktion als Handrad
Prinzipiell kann das ShuttleXpress frei in LinuxCNC konfiguriert werden, häufig anzutreffen ist aber nachfolgende Konfiguration:
- Rot (X, Y, Z, A) - Selektiert die entsprechende Achse
- Grün (Step) - Wechselt vordefinierte Schrittweiten für das "Jog Step" Rad
- Gelb (Jog Step) - Bewegt die selektierte Achse bei jedem Rastpunkt (10/Umdrehung) um die aktuelle Schrittweite
- Blau (Jog) - Bewegt die selektierte Achse durchgehend (7 Unterschiedliche Geschwindigkeiten möglich)
X, Y, Z, A
Der Button muss gedrückt und gehalten werden um die jeweilige Achse zu selektieren. Es können auch mehrere gleichzeitig gedrückt werden. Nur solange der Button gedrückt wird, kann mit einem der Jog-Räder die Achse verfahren werden.
Step
Im LinuxCNC werden verschiedene Schrittweiten definiert, die mit dem Step Button durchgeschalten werden können. Ich habe bei mir vier verschiedene hinterlegt:
- 0.005mm
- 0.01mm
- 0.1mm
- 1.0mm
Prinzipiell kann die Liste aber beliebig erweitert oder verkürzt werden.
Jog Step
Das innere Rad hat eine Rastung alle 36°, also 10 Rastungen pro Umdrehung. Mit diesem Rad wird die selektierte(n) Achse(n) pro Rastpunkt um die mit der Step-Taste eingestellte Schrittweite verfahren. Sind bspw. 0.1mm Ausgewählt, bewegt sich die Achse bei einer vollen Umdrehung des Rades um 10 * 0.1mm also 10mm.
Jog
Das Jog Wheel oder auch Shuttle-Wheel ist der äußere Ring, der sich unabhängig vom inneren bewegen lässt. Im Vergleich zum inneren gibt es hier keine Rastung und der Ring lässt sich auch nur um ca. -85° und +85° drehen. Zudem springt der Ring immer wieder auf die Ausgangsposition zurück. Mit dem Jog Wheel wird die selektierte Achse durchgehend verfahren; die Geschwindigkeit ist abhängig davon, wie weit der Ring gedreht wird. Der Encoder des Shuttle-Wheels erkennt in beide drehrichtungen jeweils 7 unterschiedliche Bereiche; die Bereiche werden mit unterschiedlichen Geschwindigkeiten konfiguriert. Damit kann man m.E. sehr Elegant verfahren, indem man vom schnellen Eilgang hin zum Zielpunkt immer langsamer langsamer wird.
Vorbereitung im LinuxCNC
Bevor wir mit der eigentlichen Konfiguration der LinuxCNC HAL anfangen können, müssen wir unser Betriebssystem vorbereiten, sodass das ShuttleXpress auch richtig erkannt wird. In dieser Anleitung gehe ich von einem "standard" LinuxCNC aus, also der fertigen Debian Distribution. Wer eine andere Installation hat, muss die die Schritte zur vorbereitung entsprechend adaptieren wenn nötig. (Alles aus der Debian Familie sollte aber analog laufen - Ubuntu bspw.)
Das shuttlexpress HAL Modul benötigt nämlich lesezugriff auf das USB Gerät (HID). Dazu muss das UDEV Subsystem entsprechend konfiguriert werden.
Das erledigen wir mit einer Regel, die wir als Datei unter /etc/udev/rules.d/99-shuttlexpress.rules
ablegen.
Inhalt der Datei ist folgender:
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0b33", ATTRS{idProduct}=="0020", MODE="0444", SYMLINK+="hidraw_shuttlexpress"
Der erste Teil ist auch in der manpage zum shuttlexpress hal modul zu finden: http://linuxcnc.org/docs/html/man/man1/shuttlexpress.1.html
Ich habe zusätzlich noch den Parameter SYMLINK+="hidraw_shuttlexpress"
angehängt. Dadurch bekommt das Gerät immer einen Symlink unter /dev/hidraw_shuttlexpress
, egal in welcher Reihenfolge man USB Geräte an den Rechner anschließt.
So können wir in der HAL Konfiguration das Gerät einfach mit dem Symlink ansprechen.
Im Normalfall sollte die UDEV Regel sofort aktiv sein, wenn nicht entweder den Rechner neu starten oder per pkill -HUP udevd den udev daemon zum nachladen der Regeln bewegen ;-)
Das sollte es auch schon gewesen sein mit der Vorbereitung.
Das ShuttleXpress sollte jetzt als Datei unter /dev/hidraw_shuttlexpress
auftauchen sobald es angeschlossen wird.
HAL Konfiguration
Die Konfiguration im LinuxCNC gestaltet sich relativ einfach, wohlgleich aber durch die begrenzten Mittel der HAL als - für mein Empfinden - einigermßen umständlich. Das meiste der HAL habe ich auch nicht selbst geschrieben sondern von einer Beispielkonfiguration aus MachineKit übernommen (configs/common/shuttlexpress.hal).
Für ein besseres Verständnis habe ich den Teil der HAL, der für die ShuttleXpress konfiguration nötig ist, versucht in einem Diagramm zu visualisieren:
Andere Formate: Draw.io Diagram - Diagram as SVG
Eingezeichnet ist eigentlich alles was für die Konfiguration notwendig ist: HAL Komponenten, Pins, Parameter samt fixer Werte und die Netze mit ihren Namen.
Die komplette Konfiguration findet ihr in meinem GitHub Repository unter https://github.com/PeterMue/ZX45-LinuxCNC/blob/master/ZX45/ZX45.hal Nachfolgend erkläre ich aber die Konfiguration auch Schritt für Schritt:
Fangen wir mit dem laden der Komponenten an:
#*******************
# ShuttleXpress
#*******************
loadusr -W shuttlexpress /dev/hidraw_shuttlexpress
loadrt abs_s32 names=abs_s32.sxp
loadrt select8 names=select8.sxp-jog-speed,select8.sxp-jog-increment
loadrt tristate_float names=tristate-float.sxp-jog-0,tristate-float.sxp-jog-1,tristate-float.sxp-jog-2,tristate-float.sxp-jog-3,tristate-float.sxp-jog-4,tristate-float.sxp-jog-5,tristate-float.sxp-jog-6,tristate-float.sxp-jog-7,tristate-float.sxp-jog-increment-0,tristate-float.sxp-jog-increment-1,tristate-float.sxp-jog-increment-2,tristate-float.sxp-jog-increment-3
loadrt scale names=scale.sxp-jog-speed
loadrt and2 names=and2.sxp-a-pos,and2.sxp-a-neg,and2.sxp-z-pos,and2.sxp-z-neg,and2.sxp-y-pos,and2.sxp-y-neg,and2.sxp-x-pos,and2.sxp-x-neg
loadrt updown names=updown.sxp-feed-cycle
loadrt ilowpass names=ilowpass.sxp-feed
Wichtig für den Moment ist erstmal nur die erste Zeile loadusr -W shuttlexpress /dev/hidraw_shuttlexpress
. Damit laden wir den "Treiber" für das ShuttleXpress.
Das Teil hängt ja per USB am Rechner und ist daher keine Realtime Komponente sondern wird stattdessen im userspace geladen (loadusr);
Mit -W
weisen wir LinuxCNC an, zu warten bis die Komponente auch bereit ist.
Die restlichen loadrt kommen gleich noch im Detail.
Weiter geht's mit den Pins des ShuttleXpress:
# --- wire shuttlexpress to meaningful signals ---
net sxp.x-button <= shuttlexpress.0.button-0
net sxp.y-button <= shuttlexpress.0.button-1
net sxp.z-button <= shuttlexpress.0.button-2
net sxp.a-button <= shuttlexpress.0.button-3
net sxp.step-button <= shuttlexpress.0.button-4
net sxp.counts <= shuttlexpress.0.counts
net sxp.spring-wheel <= shuttlexpress.0.spring-wheel-s32
net sxp.spring-wheel-f <= shuttlexpress.0.spring-wheel-f
Damit binden wir die Signal des ShuttleXpress auf sprechende Namen, die wir später verwenden können.
Als nächstes kommt die Konfiguration des "Spring-Wheel" aka. "Shuttle-Wheel" aka "Jog Wheel" aka "der äußere Ring" :-P Zuerst binde ich die einzelen Komponenten an den servo-thread, damit die Komponenten auch arbeiten können:
# bind cycle functions
addf abs_s32.sxp servo-thread
addf select8.sxp-jog-speed servo-thread
addf scale.sxp-jog-speed servo-thread
addf tristate-float.sxp-jog-0 servo-thread
addf tristate-float.sxp-jog-1 servo-thread
addf tristate-float.sxp-jog-2 servo-thread
addf tristate-float.sxp-jog-3 servo-thread
addf tristate-float.sxp-jog-4 servo-thread
addf tristate-float.sxp-jog-5 servo-thread
addf tristate-float.sxp-jog-6 servo-thread
addf tristate-float.sxp-jog-7 servo-thread
addf and2.sxp-x-pos servo-thread
addf and2.sxp-x-neg servo-thread
addf and2.sxp-y-pos servo-thread
addf and2.sxp-y-neg servo-thread
addf and2.sxp-z-pos servo-thread
addf and2.sxp-z-neg servo-thread
addf and2.sxp-a-pos servo-thread
addf and2.sxp-a-neg servo-thread
Als nächstes benötigen wir die Position des Spring-Wheels bzw. dessen Absolut Wert und eine Info ob positiv oder negativ. Dazu verwenden wir die abs_s32 Komponente.
# abs spring wheel index (ranges from -7 to +7)
net sxp.spring-wheel => abs_s32.sxp.in
net sxp.spring-wheel-abs <= abs_s32.sxp.out => select8.sxp-jog-speed.sel
net sxp.spring-wheel-is-positive <= abs_s32.sxp.is-positive
net sxp.spring-wheel-is-negative <= abs_s32.sxp.is-negative
sxp.spring-wheel
liefert einen Wert zwischen -7
und +7
; das ist die Position des Shuttle-Wheels
sxp.spring-wheel-abs
ist der Absolut-Wert und wird an select8.sxp-jog-speed.sel
weitergegeben (dazu gleich mehrer)
sxp-spring-wheel-is-positive
und -negative
liefert die Info, ob der Eingangswert positiv oder negativ ist, also ob das Shuttle-Wheel rechts oder links gedreht wurde.
Danach definieren wir, die sieben Geschwindigkeiten mit denen das Shuttle-Wheel die Achsen verfahren kann. Das ist etwas umständlich aber die HAL gibt's nicht schöner her.
# gain equals the max jog speed in mm/min
setp scale.sxp-jog-speed.gain 2000
setp scale.sxp-jog-speed.offset 0
# jog speed distribution on the spring wheel (7 steps from zero to max)
setp tristate-float.sxp-jog-0.in 0.000
setp tristate-float.sxp-jog-1.in 0.025
setp tristate-float.sxp-jog-2.in 0.050
setp tristate-float.sxp-jog-3.in 0.100
setp tristate-float.sxp-jog-4.in 0.250
setp tristate-float.sxp-jog-5.in 0.500
setp tristate-float.sxp-jog-6.in 0.750
setp tristate-float.sxp-jog-7.in 1.000
net sxp.select-jog-speed-0 select8.sxp-jog-speed.out0 => tristate-float.sxp-jog-0.enable
net sxp.select-jog-speed-1 select8.sxp-jog-speed.out1 => tristate-float.sxp-jog-1.enable
net sxp.select-jog-speed-2 select8.sxp-jog-speed.out2 => tristate-float.sxp-jog-2.enable
net sxp.select-jog-speed-3 select8.sxp-jog-speed.out3 => tristate-float.sxp-jog-3.enable
net sxp.select-jog-speed-4 select8.sxp-jog-speed.out4 => tristate-float.sxp-jog-4.enable
net sxp.select-jog-speed-5 select8.sxp-jog-speed.out5 => tristate-float.sxp-jog-5.enable
net sxp.select-jog-speed-6 select8.sxp-jog-speed.out6 => tristate-float.sxp-jog-6.enable
net sxp.select-jog-speed-7 select8.sxp-jog-speed.out7 => tristate-float.sxp-jog-7.enable
net sxp.jog-speed-factor <= tristate-float.sxp-jog-0.out
net sxp.jog-speed-factor <= tristate-float.sxp-jog-1.out
net sxp.jog-speed-factor <= tristate-float.sxp-jog-2.out
net sxp.jog-speed-factor <= tristate-float.sxp-jog-3.out
net sxp.jog-speed-factor <= tristate-float.sxp-jog-4.out
net sxp.jog-speed-factor <= tristate-float.sxp-jog-5.out
net sxp.jog-speed-factor <= tristate-float.sxp-jog-6.out
net sxp.jog-speed-factor <= tristate-float.sxp-jog-7.out
net sxp.jog-speed-factor => scale.sxp-jog-speed.in
net jog-speed <= scale.sxp-jog-speed.out => halui.jog-speed
Zunächst konfigurieren wir die scale Komponente.
Der scale.sxp-jog-speed.gain
entspricht dabei dem maximalen Vorschub in mm/min.
Anschließend konfigurieren wir die sieben Stufen (tristate-float.sxp-jog-0
bis -7
) wobei die Werte multipliziert mit dem scale.sxp-jog-speed.gain
die tatsächliche Geschwindigkeit ergibt.
(Wir könnten uns das auch komplett sparen und direkt den Wert des ShuttleXpress nehmen, da die Position des Shuttle-Wheel neben dem signed int (-7 bis 7) auch als float (-1.0 bis 1.0) ausgegeben wird. Dann könnten wir aber keine Rampe definieren, d.h. der Geschwindigkeitsanstieg pro Stufe wäre linear - wollte ich nicht)
Danach verbinden wir die Ausgänge unseres select8 mit den einzelnen enable Eingängen der sieben tristate-float. Die Funktionsweise ist dabei folgende: ein tristate-float hat einen Eingang, einen Ausgang und einen Pin für "Enable". Ist "Enable" 1 (true) dann wird der Ausgang gleich dem Eingang gesetzt. Davor hängt ein select8, das nur einen Eingang hat und 8 Ausgänge. Mit dem Eingangssignal kann hier einer der 8 Ausgänge gewählt werden, der dann einfach eine "1" ausgibt (bsp. Eingang=3, Ausgang Nr.3 = 1, die restlichen Ausgänge = 0).
Alles Zusammen:
Der Absolut Wert (0-7) des Shuttle-Wheel stuert, welcher der Ausgänge des select8.sxp-jog-speed
aktiv ist.
Jeder dieser Ausgänge aktiviert wiederum einen der tristate-float.sxp-jog-#
, was wiederum den enstprechenden (fest definierten Eingangswert) an den Ausgang weiterleitet.
Die Ausgänge der tristate-float
gehen alle auf den Eingang des vorhin definierten scale.sxp-jog-speed
, dessen Ausgang dann den Eingangswert multipliziert mit dem gain entspricht.
Diesen Wert nennen wir dann jog-speed und verbinden ich auch gleich mit halui.jog-speed
.
Damit wäre die grundlegende Funktion des Shuttle-Wheel auch schon soweit fertig konfiguriert. Was noch fehlt ist die Möglichkeit auch eine Achse zu selektieren:
# --- jog x-button activation ---
# pos
net sxp.x-button => and2.sxp-x-pos.in0
net sxp.spring-wheel-is-positive => and2.sxp-x-pos.in1
net sxp.jog-x-pos <= and2.sxp-x-pos.out => halui.jog.0.plus
# neg
net sxp.x-button => and2.sxp-x-neg.in0
net sxp.spring-wheel-is-negative => and2.sxp-x-neg.in1
net sxp.jog-x-neg <= and2.sxp-x-neg.out => halui.jog.0.minus
# --- jog y-button activation ---
# pos
net sxp.y-button => and2.sxp-y-pos.in0
net sxp.spring-wheel-is-positive => and2.sxp-y-pos.in1
net sxp.jog-y-pos <= and2.sxp-y-pos.out => halui.jog.1.plus
# neg
net sxp.y-button => and2.sxp-y-neg.in0
net sxp.spring-wheel-is-negative => and2.sxp-y-neg.in1
net sxp.jog-y-neg <= and2.sxp-y-neg.out => halui.jog.1.minus
# --- jog z-button activation ---
# pos
net sxp.z-button => and2.sxp-z-pos.in0
net sxp.spring-wheel-is-positive => and2.sxp-z-pos.in1
net sxp.jog-z-pos <= and2.sxp-z-pos.out => halui.jog.2.plus
# neg
net sxp.z-button => and2.sxp-z-neg.in0
net sxp.spring-wheel-is-negative => and2.sxp-z-neg.in1
net sxp.jog-z-neg <= and2.sxp-z-neg.out => halui.jog.2.minus
# --- jog a-button activation ---
# pos
net sxp.a-button => and2.sxp-a-pos.in0
net sxp.spring-wheel-is-positive => and2.sxp-a-pos.in1
#net sxp.jog-a-pos <= and2.sxp-a-pos.out => halui.jog.3.plus
# neg
net sxp.a-button => and2.sxp-a-neg.in0
net sxp.spring-wheel-is-negative => and2.sxp-a-neg.in1
#net sxp.jog-a-neg <= and2.sxp-a-neg.out => halui.jog.3.minus
Dazu benötigen wir unsere vorhin definierten and2 Komponenten.
Und zwar für jeden Button (X, Y, Z und A) zwei: and2.sxp-#-pos
und and2.sxp-#-neg
.
Die funktionsweise ist dabei natürlich für alle vier Achsen die gleiche, nehmen wir als Beispiel die X-Achse:
Das sxp.x-button Signal liefert uns 1 wenn der button gedrückt wurde und 0 wenn nicht.
Das verbinden wir mit dem ersten Eingang unseres and2.sxp-x-pos
.
An den zweiten Eingang kommt das Signal sxp-spring-wheel-is-positive
, das eine 1 enthält wenn das Shuttle-Wheel nach rechts bzw. eine 0 wenn nach links gedreht wurde.
Den Ausgang and2.sxp-x-pos.out
geben wir den Namen sxp.jog-x-pos
und liefern den Wert an halui.jog.0.plus
.
Fast das gleiche machen wir dann mit dem zweiten and2.sxp-x-neg
, nur dass wir als zweiten Eingang das sxp-spring-wheel-is-negative
Signal verwenden und den Ausgang auf halui.jog.0.minus
legen.
Was dabei raus kommt ist folgende Logik:
halui.jog.0.plus = (X-Button gedrückt) & (Shuttle-Wheel im Uhrzeigersinn gedreht);
halui.jog.0.minus = (X-Button gedrückt) & (Shuttle-Wheel gegen Uhrzeigersinn gedreht);
oder in Worten: Solange der X-Button gedrückt ist und das Shuttle-Wheel nach rechts gedreht ist, wird halui.jog.0.plus
auf 1 gesetzt.
und Solange der X-Button gedrück ist und das Shuttle-Wheel nach links gedreht ist, wird halui.jog.0.minus
auf 1 gesetzt.
Beides schließt sich gegenseitig aus, weswegen immer nur einer der beiden Ausgänge auf 1 sein kann.
Damit könen wir jetzt auch unsere Achsen auswählen :-)
Weiter gehts mit dem "Tick-Wheel" aka "Jog Step" aka "das Innere Rad". Auch hier erstmal die benötigten Komponenten an den servo-thread binden:
# bind cycle functions
addf updown.sxp-feed-cycle servo-thread
addf select8.sxp-jog-increment servo-thread
addf tristate-float.sxp-jog-increment-0 servo-thread
addf tristate-float.sxp-jog-increment-1 servo-thread
addf tristate-float.sxp-jog-increment-2 servo-thread
addf tristate-float.sxp-jog-increment-3 servo-thread
addf ilowpass.sxp-feed servo-thread
Was hier zu beachten ist, sind die einzelnen tristate-float Komponenten. Jede steht für eine selektierbare Schrittweite (Gewählt über den Step-Button). Wer also mehr als vier haben möchte, muss weitere tristate-float definieren.
Ich habe vier verschiedene Schrittweiten, die wie foglt definert werden:
# step increments
setp tristate-float.sxp-jog-increment-0.in 0.000005
setp tristate-float.sxp-jog-increment-1.in 0.00001
setp tristate-float.sxp-jog-increment-2.in 0.0001
setp tristate-float.sxp-jog-increment-3.in 0.001
Die Werte hier werden später noch mit 1000 multipliziert, das bedeutet ich habe 0.005, 0.01, 0.1 und 1.0mm.
Die Funktionsweise ist ähnlich wie bei den tristate-float die wir beim Shuttle-Wheel verwendet haben, nur der Trigger für das vorgeschaltet select8 ist ein anderer.
Dafür verwenden wir nämlich die updown Komponente.
Das ist im Endeffekt ein Zählwerk, das wieder beim start anfängt sobald es das maximum erreicht hat.
Wir lassen das updown.sxp-feed-cycle
von 0-3 zählen wobei jedesmal wenn der "Step-Button" gedrückt wir um 1 hochgezählt wird.
Dazu konfigurieren wir das updown:
# step increment cycle (0..3)
setp updown.sxp-feed-cycle.wrap 1
setp updown.sxp-feed-cycle.min 0
setp updown.sxp-feed-cycle.max 3
net sxp.step-button => updown.sxp-feed-cycle.countup
net sxp.jog-increment-selected <= updown.sxp-feed-cycle.count
Die beiden parameter min und max defineren die Unter- und Obergrenze und der Paramter wrap bedeutet, dass wieder von vorne Gezählt wird sobald die Obergrenze überschritten wird.
Den Step Button verbinden wir dann mit dem Eingang updown.sxp-feed-cycle.countup
und den Ausgang geben wir erstmal nur einen Namen, nämlich sxp.jog-increment-selected
.
Mit diesem Ausgang füttern wir dann unser select8.sxp-jog-increment
was wiederum unsere tristate-float aktiviert:
# select increment value, tristate to "switch" float values
net sxp.jog-increment-selected => select8.sxp-jog-increment.sel
net sxp.select.jog-increment-0 <= select8.sxp-jog-increment.out0 => tristate-float.sxp-jog-increment-0.enable
net sxp.select.jog-increment-1 <= select8.sxp-jog-increment.out1 => tristate-float.sxp-jog-increment-1.enable
net sxp.select.jog-increment-2 <= select8.sxp-jog-increment.out2 => tristate-float.sxp-jog-increment-2.enable
net sxp.select.jog-increment-3 <= select8.sxp-jog-increment.out3 => tristate-float.sxp-jog-increment-3.enable
net sxp.jog-increment <= tristate-float.sxp-jog-increment-0.out
net sxp.jog-increment <= tristate-float.sxp-jog-increment-1.out
net sxp.jog-increment <= tristate-float.sxp-jog-increment-2.out
net sxp.jog-increment <= tristate-float.sxp-jog-increment-3.out
# set jog scale
net sxp.jog-increment => axis.0.jog-scale
net sxp.jog-increment => axis.1.jog-scale
net sxp.jog-increment => axis.2.jog-scale
#net sxp.jog-increment => axis.3.jog-scale
Damit können wir nun auch schon die Einzelen Schrittweiten durchschalten. Um die Achse dazu auswählen zu können, müssen wir noch die Signal der Buttons weiterreichen:
# jog enable on button click
net sxp.x-button axis.0.jog-enable
net sxp.y-button axis.1.jog-enable
net sxp.z-button axis.2.jog-enable
#net sxp.a-button axis.3.jog-enabl
Jetzt fehlt nur noch die Drehbewegung des Rades selbst. Dazu konfigurieren wir erstmal einen ilowpass Filter:
# smooth using lowpass filter
setp ilowpass.sxp-feed.gain 0.02
setp ilowpass.sxp-feed.scale 1000
Die ilowpass.sxp-feed.scale
ist der Faktor, mit dem das Eingangssignal (einer der vier definierten Schrittweiten) multipliziert wird.
Der Output gibt entspricht dann der Distanz in mm, die eine Achse bei jedem Rastpunkt des Inneren Rades zurücklegt.
Das ist auch der letzte Schritt, nämlich den Ausgang des Lowpass Filters mit der jeweiligen Achse verbinden:
net sxp.counts => ilowpass.sxp-feed.in
net sxp.counts-smooth <= ilowpass.sxp-feed.out
net sxp.counts-smooth => axis.0.jog-counts
net sxp.counts-smooth => axis.1.jog-counts
net sxp.counts-smooth => axis.2.jog-counts
#net sxp.counts-smooth => axis.0.jog-counts
Geschafft!
Damit ist die Konfiguration im LinuxCNC abgeschlossen und das ShuttleXpress kann als Handrad verwendet werden.