Nachdem ich zwei 3DTouch Sensoren für die Höhenprofilerstellung mittels OpenCNCPilot in Verbindung mit einer Standard GRBL Version an einer CNC-Fräse umgebaut hatte - die erste Quick&Dirty Version und der Nachfolger in schön und praktisch für nachträgliche Anpassungen - und sich deren Brauchbarkeit im praktischen Einsatz erwiesen hatte, überlegte ich mir eine Vereinfachung im Sinne von “einfacher nachzubauen”. Schließlich möchte oder kann sich nicht Jedermann mit den Innereien des Sensors abgeben um ihn an seiner Fräse einzusetzen. Aber Abhilfe ist möglich :)
Der klassische 3DTouch Sensor senkt und hebt den Taststift vom Controller des 3D-Druckers gesteuert. GRBL für CNC-Fräsen stellt diese Ansteuerung nicht zur Verfügung, also muss die Steuerung des Stiftes irgendwie anders erfolgen.
Der Ausweg ist die Zwischenschaltung einer kleinen Elektronik, die den Stift steuert, das Probe-Signal des Sensors aber direkt an GRBL weiterleitet, damit keine Verzögerungen impliziert werden. Die Steuersignale zum Anheben und Absenken des Taststiftes werden mit einem Microcontroller erzeugt, dessen Funktion erschöpft sich im Erkennen des Probesignals und der Erzeugung von Signalen für aus dem Modellbau bekannte Servos.
Ein kleines Problem existiert in Form des Pegels der Meldung eines Touchevents. Die 3DTouch Sensoren melden Kontakt mit einem Aktiv HIGH Signal. An der Fräse hat sich hingegen eingebürgert, dass ein Touchevent als Aktiv LOW Signal gemeldet wird, da z.B. beim Erstellen eines Höhenprofils einer Leiterplatte die Platine mit Masse zu verbinden ist und der Taststift den Kontakt nach Masse meldet.
GRBL lässt sich zwar umparametrieren, mit $6=1 reagiert GRBL auf ein aktiv HIGH Signal am Probe-Eingang. Will man aber nichtleitende und leitende Materialien wechselweise abtasten, sollte der Einfachheit halber beides mit der gleichen Polarität gemeldet werden.
Folglich muss das Ausgangssignal des Sensors invertiert werden, bevor es an GRBL weitergeleitet wird. Die Invertierung mit dem µC wäre prinzipiell möglich, um aber Verzögerungen so weit wie möglich zu vermeiden, wird das Signal mit einem Transistor oder MOSFET invertiert.
Damit die Schaltung schön klein ausfällt, verwende ich als Microcontroller einen Digispark Baustein. Der lässt sich einfach über USB programmieren und hat genügend Ein- und Ausgänge für den gedachten Einsatzfall.
Die Schaltung ist unspektakulär und besteht im Wesentlichen aus dem Digispark und ein paar Steckern. Der Inverter für das Probe Signal in Form eines Transistors oder MOSFET kommt hinzu, ein Blockkondensator verhindert Störungen.
(Click für größere Darstellung)
Die Stecker für den Anschluss des 3DTouch sowie den Ausgang Richtung GRBL habe ich in der abgewinkelten Version vorgesehen, der Digispark ist ebenfalls steckbar. Alle Bauteile bis auf den MOSFET sind normale TH Bauteile, der FET ist SMD und wird ggf. auf der Unterseite der Platine montiert.
Es darf natürlich nur entweder der MOSFET oder der Transistor bestückt werden. Bei Verwendung des MOSFET ist R2 zu bestücken, wird der Transistor eingesetzt, müssen stattdessen R3 und R4 eingelötet werden.
Sollte der eigene Touch Sensor ein aktiv LOW Signal erzeugen, kann die Invertierung durch setzen einer Lötbrücke umgangen werden. In diesem Fall werden der Transistor, der MOSFET und die Widerstände R2..R4 nicht bestückt.
Sollte der wechselnde Einsatz mit leitfähigem und nicht leitendem Material nicht geplant sein, man also immer nur den Sensor einsetzt, kann auf die Invertierung per Transistor oder FET natürlich ebenfalls verzichtet werden und man stellt die passende Polarität in GRBL ein.
Update
Nach einigen Irrwegen durch die Syntaxgepflogenheiten des Digispark Biotops habe ich heraus bekommen, dass der Aufruf
attachInterrupt(0, SensorInput, RISING);
als ersten Parameter nicht die Pin-Nummer sondern die gewünschte Interrupt-Nummer erwartet. Ok, das hätte man aus der Tatsache schließen können, dass beim Arduino traditionell das Makro digitalPinToInterrupt(Pin-Nummer) als erster Parameter angegeben wird, also
attachInterrupt(digitalPinToInterrupt(Pin-Nummer), SensorInput, RISING);
und man sich den Namen des Makros mal im Ohr zergehen lässt. Das Makro wandelt beim Arduino die Pin-Nummer in die zugehörige Interrupt Nummer um.
Dieses Makro gibt es bei Digispark nicht, es lässt sich aber leicht aus der Arduino-Version ableiten:
// Definition von digitalPinToInterrupt() für Digispark. Für den AtMega (Arduino) ist das Makro bereits (anders) definiert
#ifndef digitalPinToInterrupt
#define NOT_AN_INTERRUPT -1
#define digitalPinToInterrupt(p) \
((p) == 2 ? 0 : \
((p) == 0 || (p) == 1 || (p) == 3 || (p) == 4 || (p) == 5) ? 1 : NOT_AN_INTERRUPT)
#endif
Aufgedröselt ergibt sich, dass PB2 im IRQ0 resultiert, alle anderen Pins des AtTiny im IRQ1, wobei PB5 normalerweise RESET ist und somit keine nutzbaren Interrupts erzeugt.
Nachdem diese Hürde umschifft war, konnte ich feststellen, dass meine Pinzuweisung mit PB0 als Eingang für das Sensorsignal vom 3DTouch und PB2 als Ausgang für das Steuersignal zum Sensor etwas unglücklich gewählt war. Cleverer weil zielführend wäre gewesen, diese beiden Signale umgekehrt zuzuweisen, also PB2 als Eingang, der bedient nämlich den INT0 Interrupt, und PB0 als Ausgang zum Steuern des Sensors.
An meinem bereits fertig aufgebauten Testboard kann ich diese Änderung mit zwei kleinen Cutter-Schnitten und zwei kurzen Drähten realisieren und so die Programmentwicklung abschließen.
Für den geneigten Nachbauer gibt es natürlich die aktualisierte Version.
(Click für größere Darstellung)
Wer die Schaltung nachbauen will, findet hier die Unterlagen im EAGLE V7 Format.
Update
Da an meiner Fräse keine 5 V Versorgung in unkompliziert erreichbarer Nähe zur
Verfügung steht, der Digispark aber einen ausreichend dimensionierten 5 V Spannungsregler an Bord hat, habe ich eine weitere Version erstellt, die diesen Spannungsregler zur Versorgung des Sensors einbindet.
(Click für größere Darstellung)
Der Stecker Richtung Fräsen-Controller ist jetzt 4-polig und führt sowohl 5 V als auch 12 V als Eingang.
Soll die Schaltung mit 12 V versorgt werden, sind die im Bild oberen Drei die Pins der Wahl, die Belegung ist dann (von oben zählend)
Erfolgt die Versorgung mit 5 V, werden die im Bild unteren drei Pins verwendet, die Belegung ist dann (von oben zählend)
Den alternativen Transistor habe ich aus Platzgründen entfernt, der Lötjumper zum Überbrücken des (dann nicht zu bestückenden) FET blieb erhalten.
Auch hierfür stelle ich die Unterlagen im EAGLE V7 Format zur Verfügung.
Hinweis
Der Spannungsregler auf dem Digispark ist ein 78M05, dessen zulässige Eingangsspannung 35 V beträgt. Falls also an der eigenen Fräse weder 5 V noch 12 V zur
Verfügung stehen, kann eine beliebige Gleichspannung bis zu diesem Wert am obersten Pin angeschlossen werden. Gegebenenfalls sollte bei hohen Spannungen die Erwärmung
des Reglers geprüft werden. Ich erwarte aber keine Probleme, da die Stromaufnahme des 3DTouch Sensors immer nur kurzzeitig beim Ein- oder Ausfahren des Pin ansteigt.
Hinweis
Wenn man auf seiner Fräse immer nur nichtleitendes Material verarbeitet und somit die
Polarität des Touch-Signals fest in GRBL umstellen kann (Parameter $6=1), können der FET und R1 entfallen, der Ausgang des Sensors wird dann über den Löt-Jumper direkt mit dem GRBL Controller verbunden.
Das fertige Programm ist im Prinzip recht übersichtlich gestaltet, der etwas größere Umfang ergibt sich aus der Möglichkeit, als Controller alternativ einen Arduino Nano oder Uno zu verwenden. Möchte man diese Möglichkeit nutzen, einfach in der INO Datei direkt unter dem einleitenden Kommentar das Define NANO einkommentieren (Kommentarzeichen davor löschen). Die Anschlüsse des Sensors an die Hardware sucht man sich in diesem Fall aus den Definitionen im Code heraus, man suche nach der Zeile
// Definition der Pins.
Der hier vorgestellte Code funktioniert mit einem 3DTouch Sensor der neuesten Generation (Platine mit außenliegendem Stecker für die Anschlüsse), ob er auch mit einem 3DTouch oder einem Original BLTouch Sensor zusammen arbeitet, kann ich mangels passender Hardware nicht selbst überprüfen. Falls jemand die Schaltung nachbaut und mit einem alten oder älteren Sensor testet , freue ich mich über Rückmeldungen.
Update
Der vom 3DTouch gelieferte Impuls ist mit 10 ms deutlich zu kurz, GRBL erkennt das nicht als Probe Event.
Abhilfe: Der AtTiny auf dem Digispark bekommt ja sowieso den Trigger-Impuls von Sensor um den Timer zu starten, der dafür sorgt, dass der Pin des Sensors nach einem Touch-Event zeitgesteuert wieder ausgefahren wird. Jetzt ziehe ich gleichzeitig einen weiteren IO des AtTiny (PB3) auf LOW, der parallel zum Ausgang des FET verdrahtet wird. Dieser Ausgang schaltet Laufzeit bedingt etwas verzögert auf LOW, da aber der FET das Sensor-Signal mehr oder weniger unverzögert durchschaltet, hat der Microprozessor 10 ms Zeit, den Ausgang zu aktivieren.
In den folgenden Bildern stellt das blaue Signal den Ausgangsimpuls des 3DTouch dar, der gelbe Kurvenzug ist das Signal am Ausgang des Interface.
Das klappt prima, auf dem Oszi sieht man schön, wie der µC nach 10 ms “übernimmt” (die kleine Stufe im gelben Signal nach der fallenden Flanke des blauen Signals).
Der resultierende Impuls am Ausgang Richtung GRBL hat in Summe dann ca. 320 ms:
Das geänderte Schaltbild zur oben beschriebenen Erweiterung...
(Click für größere Darstellung)
sowie das Layout
Hier also die aktualisierte und zu Version 1.3 des Interface passende Firmware V1.2 für den Controller (Digispark oder Arduino), die zusammen die Oberflächenabtastung von nichtleitenden Materialien mit Hilfe eines unveränderten 3DTouch oder BLTouch Sensors in Verbindung mit GRBL V1.1 erlauben.
Hinweis
Wird der Sensorpin blockiert, kann also nicht den Kommandos für Aus- oder Einfahren folgen, geht der Sensor in Störung und blinkt fortan trotzig mit der roten LED.
Aus diesem Zustand kann er nur noch durch abschalten der Versorgungsspannung erlöst werden - > Power Cycle.
Leider kann ich mangels Hardware keine Vergleichsmessungen zwischen dem alten und neuen Design der 3DTouch Sensoren durchführen, meine alten 3DTouch Sensoren sind allesamt auf meine eigene Firmware mit negativem Impuls umgeflasht und somit nicht mehr am Interface betreibbar.
Ich kann also nicht sagen, ob die beobachteten Ungenauigkeiten von meinem Interface oder vom neuen Sensordesign verursacht werden.
Wer mich kennt oder zumindest Teile meiner Homepage gelesen hat, weiß, das hält mich nicht lange auf...
Da ich am umgebauten 3DTouch Sensor V2 einen Programmieranschluss nach außen
geführt habe, kann ich die Firmware problemlos so anpassen, dass der generierte Touch-Impuls aktiv HIGH ist und somit kompatibel zum 3DTouch Interface.
Das ist mittlerweile zumindest teilweise geklärt, Ergebnisse hier.