
Mit OpenCNCPilot (OCP) steht ein schicker, funktional hervorragend aufgestellter und auch noch kostenfrei nutzbarer G-Code Streamer zur Verfügung. OCP setzt auf GRBL auf, einem extrem optimierten G-Code Parser und Step-Impuls-Erzeuger für CNC-Maschinen, basierend auf Arduino.
Mit Erscheinen der Version V1.1 wurde in GRBL die Fähigkeit eingebaut, die Maschine mittels sogenannter Jog-Befehle manuell zu bewegen. OCP stellt diese Möglichkeit zur Verfügung, allerdings nur als Tastaturbefehl, heißt, man bereitet das manuelle Verfahren vor, dann kann mit den Pfeiltasten der Fräskopf gesteuert werden, eingeschränkt mittels Voreinstellungen in Geschwindigkeit und maximal zurückzulegender Entfernung.
Mit Implementierung der Joystick-Steuerung in OCP liegt es nahe, auch die Unterlagen zur Herstellung eines mit OCP nutzbaren Joystick zu veröffentlichen um damit eventuell die Akzeptanz dieser Art der Steuerung in einem größeren Nutzerkreis zu erhöhen.
Neben der Erweiterung von OCP müssen zwei Daumenjoysticks so montiert werden, dass sie bequem bedient werden können. Den Joystick ein- und ausschaltbar zu machen und ein paar LEDs für Anzeigen hinzuzufügen, bieten sich ebenfalls an.
Ich habe die Bedienung meiner CNC-Fräse mittels Joysticks schon vor geraumer Weile etwas anders gelöst. Der Umstieg auf GRBL-Jogging lässt mich das Thema noch einmal aufgreifen.
Die Bearbeitung des damals genutzten Alu-Gehäuses war kein Spaß, weshalb ich diesmal den 3D-Drucker bemühe, um das Gehäuse zu erstellen. Dieser Ansatz hat den bestechenden Vorteil, das die Ausbrüche für die Joysticks und Schalter nicht mühsam aus dem Alu geschnitzt werden müssen, sondern einfach nicht gedruckt werden. Der Innenteil zur Befestigung der beiden Daumen-Joysticks wird gleich mitgedruckt.
Das Gehäuse-Unterteil bekommt eine Zugentlastung für das Anschlusskabel, der Block für die Montage der beiden Daumen-Joysticks wird getrennt gedruckt, damit die Sticks angeschraubt werden können, ohne Löcher im Gehäuse vorsehen zu müssen. Gleichzeitig hat mir dieser Ansatz die Möglichkeit gegeben, Anpassungen an den Befestigungslöchern ohne großen Aufwand zu realisieren - nur der Block musste neu gedruckt werden.
Als Schaltelemente habe ich diesmal 22 mm durchmessende Schalter/Taster, jeweils mit eingebauter LED, verwendet. Der Schalter hat einen rot beleuchtbaren Ring, der Ring am Taster kann grün beleuchtet werden. Siehe dazu auch hier.
Die Daumen-Joysticks mit Poti der ersten Ausführung im Alu-Gehäuse haben bis zuletzt prima funktioniert, nicht zuletzt dank der ausgebufften Firmware, die die mechanischen Unbilden der Billig-Joysticks perfekt ausgeglichen hat.
Trotzdem habe ich mich entschlossen, den neuen Joystick mit sogenannten TMR-Sticks auszustatten. Bekannte Hersteller von TMR-Sticks sind Gulikit und K-Silver, viele Anbieter von PlayStation-Upgrades nutzen diese Sticks und loben sie über Alles, sie sind aber sehr teuer. Ich habe preiswerte TMR-Sticks von Ginfull verwendet.
Hinweis:
Der Metallkäfig dieser Sticks hat von oben betrachtet Abmessungen von 13 x 13 mm.

Das Layout für den TMR Daumen-Joystick.

Durch die Verwendung des Metallrahmens der Mechanik als Masse-Verbindung kann das Layout einseitig entflochten werden.
Hier ein Größenvergleich zwischen einem herkömmlichen Daumen-Joystick und einem der neuen TMR-Versionen:

Diese Sticks haben keine traditionellen Potentiometer, sondern die Mechanik schwenkt einen kleinen Magneten an einem Hall-Element vorbei, das mittels integrierter Elektronik aus dem detektierten Magnetfeld eine Gleichspannung ableitet, die dann mit dem Arduino als Hirn passend weiter verarbeitet wird.
Zu beachten ist hierbei, dass die TMR-Elektronik mit maximal 3,6 V beaufschlagt werden darf. Ein 1:1 Umbau des alten Joystick auf diese Technik kommt also nicht in Frage, die vormals verbauten Potis arbeiten mit 5 V.
Eine knifflige Angelegenheit ist es, technische Unterlagen zu diesem TMR-Sticks zu finden. Ein einziger chinesischer Anbieter stellt solche Unterlagen für seine Sticks zur Verfügung , allerdings mit chinesischer Beschriftung und für viele verschiedene Typen auf einer Seite. Ginfull, der Hersteller meiner Daumen-Sticks bietet keinen solchen Service.
Natürlich gibt es unterschiedliche Ausführungen der Joysticks im Sinne der Pin-Belegung der TMRs. Die Spannungsversorgung liegt immer auf den beiden äußeren Pins, aber Pin 1 und Pin 3 sind mal mit 5V/GND belegt, mal mit GND/5V. Bei einem Poti ist es egal, wo an den äußeren Pins Plus oder Masse angeschlossen wird. Die TMR-Bauteile haben aber eine Elektronik eingebaut, die Polung muss also beachtet werden.
Meine TMRs sind nicht beschriftet, also hilft nur Trial&Error...
Ein Labornetzteil auf die niedrigste zugelassene Betriebsspannung der TMRs von 1,8 V
eingestellt und die Strombegrenzung nach unten gesetzt - Spannung kurz anlegen, Strom beobachten... Oha, über 100 mA! Die Elektronik der TMRs soll einige hundert µA ziehen,
also habe ich nach Murphy zielsicher die falsche Polung erwischt. Gegentest - schließlich will ich ja wissen, ob ich meinen TMR-Baustein bei dem Test in die ewigen Jagdgründe
geschossen habe. Glück gehabt, der Ausgang liefert sauber 0 V bis nahezu 1,8 V, Mitte bei 912 mV.
Der Ausgang des TMR arbeitet ratiometrisch, mit einer Versorgungsspannung von 3,3 V, wie sie der Arduino zur Verfügung stellt, wird das Ausgangssignal also zwischen 0 V und 3,3 V liegen, in Mittelstellung dann bei ca. 1,65 V.
Schlimmer war jedoch, dass die von mir gekauften Sticks andere Abmessungen haben, als jeder der angebotenen Typen im Datenblatt. Die korrekten Maße für die Pins mit der Schieblehre am Bauteil abnehmen ist gar nicht so einfach...
Um also die Sticks mechanisch im Gehäuse befestigen zu können, musste ich ein passendes Layout erstellen. Ich habe mich bei der Festlegung der Abmessungen der Platine und der Steckerbelegung an vorhandenen Poti-Lösungen orientiert und die Stick-Achse an derselben Stelle des Layout platziert. Das hilft bei der Umsetzung des Blocks zur Befestigung im Gehäuse.
![]()
Der zugehörige Schaltplan:
(Click auf das Bild für volle Auflösung)
Für den TMR Daumen-Joystick habe ich eine Library erstellt, die ich zur Verfügung stelle. Achtung: Die Library passt genau zu meinem Ginfull Stick, TMR-Sticks anderer Hersteller haben ggf. andere Abmessungen und Pinbelegungen, wie ich beim Vergleich mit dem gefundenen Datenblatt feststellen musste. Layout und Schaltplan im Format EAGLE V7.7 sowie die Library finden sich in der verlinkten ZIP-Datei.
Der steuernde Arduino benötigt ebenfalls ein geändertes Layout seiner Adapterplatine. Um den Joystick mit 3,3 V versorgen zu können, muss zum einen der Stecker Richtung Joystick-Gehäuse von 5 V auf 3,3 V umgeroutet werden, zum anderen muss der Pin AREF mit dem 3,3 V Anschluss des Arduino verbunden werden. Hier ist zu beachten, dass eine direkte Verbindung eher unpraktisch ist, denn wenn AREF fest auf 3,3 V liegt und der Arduino im Code noch nicht auf Analogreferenz “EXTERN” umprogrammiert ist, wird der Pin intern spätestens bei der ersten Analogwandlung mit 5 V verbunden. Autsch!
Hier wird also ein Serienwiderstand von 4,7 kΩ vorgesehen.
Zur Beachtung: Der Serienwiderstand arbeitet mit dem Innenwiderstand des AREF
Eingangs von typisch 32 kΩ als Spannungsteiler. Die Referenzspannung reduziert sich dadurch auf ca. 2,88 V, was bewirkt, dass der gemessene Vollausschlag (1023 am
Ausgang des ADC im Arduino) bereits bei ca. 95% Ausschlag des Knüppels erreicht wird.
Das wird programmtechnisch in der Firmware des Joystick abgefangen, indem ich die Werte für oberen und unteren Anschlag des TMR messe und mit der map-Funktion auf die erwarteten Werte zwischen 0 und 1023 aufblase. Ich gehe mal mit Schätzwerten von 120 und 1000 ins Rennen. Wird gegebenenfalls nach der Messung noch angepasst.
Um das Design flexibel zu halten, gibt es einen Jumper zur wahlfreien Selektion von 5 V oder 3,3 V für den Joystick.
Hier das Schaltbild...
(Click auf das Bild für größere Darstellung)
... und das Layout

Die passende Firmware für den Arduino stelle ich zur Verfügung. Am Anfang der Datei findet sich eine umfangreiche Dokumentation mit Hinweisen. In der momentanen Fassung ist der Betrieb mit den TMR-Joysticks eingestellt, aber über Defines im Code kann auch die Erzeugung von Impulsen für die Stepper-Endstufen eingestellt werden. In diesem Fall sollte eine Trennung der Endstufeneingänge vom GRBL Arduino vorgesehen werden, beispielsweise mit einem wie hier beschriebenen Interface.
Ich habe das damals erstellte Modell des Alu-Gehäuses als Grundlage genommen, einige Parameter geändert und jeweils eine STL-Datei für jedes Teil - Boden, Deckel und Montageblock - erzeugt.

Geändert ist beispielsweise der Durchmesser der Löcher für die Schalter. Die Schalter haben heute 22 mm Durchmesser, damals nutzte ich 19 mm durchmessende Teile - bitte die Anmerkung beachten. Die Löcher für die Joystick-Kappen musste ich etwas verschieben, genauso die Löcher für die Befestigung der Daumen-Sticks am Block. Der Deckel rastet sauber auf dem Unterteil ein, trotzdem würde ich sicherheitshalber die vier Schrauben an den Ecken eindrehen.
Das Kabel muss acht Adern haben, eine Schirmung ist empfehlenswert. Ich habe Kabel von Verlängerungen für RS232 Verbindungen benutzt. Der Außendurchmesser des Kabels ist ca. 6 mm, das im Gehäuse vorgesehene Loch und der Klemmkanal (Zugentlastung) könnten mit 5 mm also etwas zu eng ausgefallen sein. Da ich die Source im Format Designspark Mechanical V6 beilege, kann das jeder selbst an sein Kabel anpassen. Ich habe alternativ das vorhandene Loch vorsichtig mit einem 6 mm Bohrer etwa 15 mm tief aufgebohrt, das Kabel sitzt jetzt klemmend ziemlich fest im Loch, der Mäanderkanal fasst nur noch locker die von der Schirmung umhüllten Drähte.

In der ZIP-Datei sind neben den Sourcen auch die STL-Dateien der drei Einzelteile des Gehäuses enthalten, die können direkt auf den Slicer losgelassen werden.
Mit dem Block wie beigefügt stimmen die Abmessungen der oben beschriebenen und verlinkten Daumen-Joystick-Platinen ziemlich gut, alles kann mit M3 Senkkopf -Schrauben einfach zusammengeschraubt werden. Zuerst die beiden Daumen-Joysticks an den Block, dann den Block von außen im Gehäuse verschrauben. Zum Verdrahten die Enden am Kabel lang genug lassen (ca. 15 cm), die Schalter sitzen im Deckel und der muss fertig verdrahtet aufgesetzt werden.
Hier ein paar Ansichten des mechanisch fertig aufgebauten Joystick. Die beiden Breakout Boards mit den Sticks sind mit jeweils zwei M3 Senkkopfschrauben am Block befestigt.

Die beiden Schalter sind so orientiert, dass die LED-Anschlüsse parallel verdrahtet werden können, das gilt zumindest für GND.
Das fertig zusammengebaute Gehäuse.

Die Verdrahtung im Joystick ist lose verteilt, beim Zusammenbau muss man die Drähte vorsichtig ins Gehäuse versenken und beim Schließen des Deckels aufpassen, die Drähte nicht einzuklemmen.
Die Schirmung habe ich im Joystick mit der Masse der Stromversorgung verbunden. Um Kurzschlüsse beim Schließen des Gehäuses sicher zu verhindern, habe ich das Geflecht mit einem Schrumpfschlauch umhüllt.
Der Verdrahtungsplan dürfte hilfreich sein:
(Click auf das Bild für volle Auflösung)
Achtung
Nicht vergessen, dass bei Einsatz der TMR-Sticks unbedingt auf die Polung der Betriebsspannung am TMR-Element geachtet werden muss. Bei Verwendung des oben verlinkten Breakout-Board in Verbindung mit den von mir eingesetzten Ginfull TMRs ist das gewährleistet. Wer andere TMRs einsetzt, muss selbst darauf achten.
Hier noch die Aufstellung, wie ich Kabelfarbe und Funktion einander zugeordnet habe:
Dabei kann jeder nach eigenem Gutdünken verfahren, ich muss aber darauf achten, dass die Zuordnung exakt der im alten Joystick entspricht, da ich ja den neuen Joystick an denselben Port am Rechner anschließen will.
Hier noch die korrespondierende Belegung im Stecker:
Als Vertrauen bildende Maßnahme stelle ich Bilder des geöffneten Steckers zur Verfügung. Die Zählung beginnt links oben am breiteren Rahmen mit 1.

Hier die Ansicht der längeren Reihe 8..1 (Pin 1 ist im Bild rechts).

Und letztlich die schmalere Reihe 9..15 (Pin 9 ist im Bild links).

Wenn Fehler in der Benummerung vorhanden sind, bitte gerne eine Rückmeldung schicken :)
Nachdem die Vorarbeiten soweit erledigt sind, muss jetzt noch der Joystick-Arduino mit der passenden Firmware geflasht werden.
Im wesentlichen ist die Firmware gleich geblieben, d.h. die Methode zur Festlegung der Mittenposition der Sticks und das Auslesen der Analogwerte per interruptgesteuerter AnalogScanner-Lib ist identisch. Lediglich die Aufbereitung der Befehle für OCP wurde zusätzlich implementiert. Natürlich musste die Logik so erweitert werden, dass sowohl der Step-Impuls-Modus von früher als auch der neue GRBL-Modus wahlweise eingeschaltet werden kann.
Da der Joystick neben den beiden Daumen-Joysticks zwei Schaltelemente SCHALTER und TASTER hat, habe ich die Umschaltung des Modus über Schalter-/Taster-Voodoo realisiert.
Hier stichwortartig die Bedienung der beiden Schaltelemente:
Stepper-Mode benutzen:
SCHALTER ist AUS, Grüne LED blinkt nicht
SCHALTER auf EIN -> Joystick übernimmt die Stepper und erzeugt Step-Impulse direkt. Kein Koordinaten-Tracking durch OCP. OCP kann die Stepper nicht bedienen.
X- oder Y-Achse fixieren:
SCHALTER ist EIN, Grüne LED blinkt nicht
Solange SCHALTER EIN ist + TASTER festhalten + X/Y-Stick KURZ in die gewünschte Richtung
kippen -> Gründe LED blinkt mit 1 Hz (langsam).
Die andere Achse wird gesperrt und kann per Joystick nicht mehr bewegt werden. Die bewegte Achse und Z sind frei:
In diesem Modus kann per Joystick eine Gerade in X oder Y abgefahren werden -> Gerader Schnitt im Material möglich.
Solange SCHALTER EIN ist und Grüne LED mit 1 Hz blinkt, kann dieser Modus mit TASTER
abgeschaltet werden.
Umstellung des Joystick-Arduino auf GRBL-Jogging:
Schalter ist AUS, Grüne LED blinkt nicht.
TASTER festhalten + SCHALTER auf EIN -> Rote LED ist AN, Grüne LED blinkt mit 3 Hz (schnell) -> GRBL-Mode aktiv -> Joystick sendet Stick-Werte an OCP, OCP trackt die Koordinaten.
Solange SCHALTER EIN ist, kann OCP per Joystick gesteuert werden (nicht vergessen, die Bedingungen für Jogging in der GUI zu aktivieren!).
In diesem Zustand kann die Maschine sowohl von OCP als auch vom Joystick gesteuert werden.
TASTER kurz (< 1 s) drücken -> Joystick-Mittenwerte werden neu gesetzt (stoppt "wandern" bei schlechten Sticks).
SCHALTER AUS -> Joystick ist deaktiviert, Gründe LED blinkt weiter.
GRBL-Modus benutzen:
Grüne LED blinkt mit 3 Hz.
SCHALTER auf EIN -> GRBL-Modus ist wieder direkt aktiv, Gründe LED blinkt.
GRBL-Mode deaktivieren:
SCHALTER ist EIN, Grüne LED blinkt.
TASTER > 3 s festhalten -> GRBL-Mode wird deaktiviert -> Grüne LED ist AUS.
Hinweis: Die geänderte Firmware darf nicht auf den vorhandenen Joystick-Arduino aufgespielt werden, ohne das alte Breakout-Board durch die Version V2.2 zu ersetzen!
Hintergrund: Die TMR-Sticks arbeiten mit einer Betriebsspannung von maximal 3,6 V.
Ich verwende den auf dem Arduino Nano vorhandenen 3,3 V Spannungsregler für die
Versorgung der TMR-Sticks. Diese Änderung ist erst mit Einführung der Platinenversion V2.2 realisiert, bei älteren Versionen wird der Joystick mit 5 V versorgt.
Durch die Anpassung der Versorgungsspannung liegt die Ausgangsspannung des TMR-Elements im Bereich 0..3,3 V. Um die Auflösung am Analogeingang des Arduino nicht einzuschränken, muss die Referenz des AD-Konverters auf EXTERN gestellt und der AREF Pin ebenfalls mit den 3,3 V versorgt werden.
Der 3,3 V Pin und der AREF Eingang werden deshalb mit einem 4,7 kΩ Widerstand verbunden, um versehentliches Betreiben des AD-Wandlers mit der Einstellung INTERN für die Referenz nicht zum Desaster werden zu lassen. Ohne den Schutzwiderstand würde in diesem Fall die interne 5 V-Referenz auf den AREF Pin geschaltet werden, an dem 3,3 V vom externen Spannungsregler anliegen. Irgend ein Bauteil im µC oder der Regler selbst würden das über kurz oder lang mit finaler Verweigerung der Zusammenarbeit quittieren.
Aber auch hier treffen Theorie und Praxis leider diametral aufeinander. Der Widerstand in Serie bildet mit dem Innenwiderstand des AREF Pins von ca. 32 kΩ gegen Masse einen Spannungsteiler, die Referenzspannung für den AD-Wandler ist also nicht 3,3 V, sondern etwas kleiner. Mit der Formel zum Spannungsteiler

kommt man mit 4,7 kΩ auf eine Referenzspannung von ca. 2,88 V.
Tests und Messungen mit diesem Setup ergeben, dass die Auflösung des AD-Wandlers durch die zu kleine Referenzspannung doch recht stark eingeschränkt wird. Der untere Wert und die Mitte stimmen zwar, aber die Auslenkung nach oben ist elektrisch unsymmetrisch stark verkürzt, der Bereich oberhalb von 2,88 V wird ignoriert, Vollausschlag wird vom Arduino schon bei ca. 85% vermeldet.
Die Änderung des Widerstands auf 1 kΩ ergibt schon bessere Ergebnisse. Die Spannung am AREF Pin liegt dann bei ca. 3,2 V und die Strombelastung für den Pin liegt mit ca. 2,2 mA im Worstcase (3,3 V von außen über 1 kΩ gegen intern 5 V, wenn vergessen wird, die Referenz im Code vor der ersten Messung auf EXTERN zu schalten) noch im Rahmen.
Zusammen mit dem leichten Abfall der Versorgungsspannung durch die rote LED im Schalter, ergeben sich Ausgangsspannungen an den TMRs von etwas über 3 V (gemessen 3,104 V an einem der TMRs), was gut zu der sich ergebenden Referenzspannung passt.
Trotzdem war ich noch nicht zufrieden mit dem Ergebnis, zumindest nicht für die Y-Achse. In der Praxis hat sich herausgestellt, dass die Verfahrgeschwindigkeiten links und rechts deutlich unterschiedlich sind und alle Versuche, dieses Verhalten per Software in den Griff zu bekommen, scheiterten. Irgendwann kam ich dann auf die Idee, mir einmal die Mechanik anzuschauen.
Das sieht ja noch ganz gut aus...

... aber hier tritt das Problem deutlich zutage:

Der Knopf wird vom Schalter gestoppt, bevor er den Endausschlag erreichen kann. Jetzt muss doch Plan B in Kraft treten, 19 mm durchmessende Schalter und Taster müssen her.
Das geht natürlich einher mit einem neuen Deckeldesign, durch die vorhandenen 22 mm Löcher fallen die kleineren Schalter einfach hindurch. Ich habe die Platzierung der beiden Schaltelemente dann gleich noch ein bisschen egalisiert und den Abstand zu den inneren Rändern vergrößert, so dass die Muttern zur Befestigung besser bedient werden können.

Zusätzlich habe ich die Lage des Ausschnitts für den XY-Stick korrigiert, so dass er jetzt genau zentriert im Loch sitzt. Dadurch kann das Breakoutboard für den Stick mit zwei dünnen Kunststoff-Beilagscheiben ein kleines Bisschen nach oben korrigiert werden, so dass der Abstand zwischen Knopf und Schalterrand noch besser passt.
Die geänderten Designfiles inklusive STL-Dateien für den Slicer zum Download.
Noch ein paar Worte zur Firmware:
In der aktuellen Firmware V5.9.2 habe ich vorgesehen, sowohl Sticks mit normalen Potis als auch TMRs einsetzen zu können, die zu nutzende Referenzspannung für den AD -Wandler kann über das Menü eingestellt werden. Also liegt es nahe, eine Möglichkeit vorzusehen, die maximalen Ausschläge der Sticks kalibrieren zu können.
Ich habe eine Routine eingebaut, die alle Maximalausschläge der verwendeten Sticks ausmisst und im EEPROM speichert. Sollte also mal einer der Sticks kaputt gehen, kann er problemlos ausgetauscht werden, ohne dass an der Firmware etwas geändert werden muss. Die Kalibrierroutine wird per Menü gestartet und mit dem Schalter am Joystick wieder abgeschaltet, nachdem man alle Sticks ein paarmal langsam im Kreis bzw. hoch und runter bewegt hat.
Nachdem ich die kalibrierten Wert jetzt auch nutze - da waren noch drei versteckte Aufrufe an “hole Joystick-Werte” nach dem Setzen der kalibrierten Werte im Code übrig geblieben, funktioniert sowohl die Impulserzeugung im Joystick, die passenden Umschaltung des Interface in den verschiedenen Betriebsmodi und das Jogging über OCP und GRBL wie seit Wochen vorgesehen. Die dafür notwendige Firmware V5.9.2c kann geladen werden.