Sensorbestückung und Datenlogging

Motivation

3D-Drucker sind immer mehr im Kommen. Sie ermöglichen es, Prototypen und Kleinstserien in kürzester Zeit anzufertigen, und mit einem etwas höheren Aufwand sind auch durchaus etwas aufwendigere Drucke möglich.
Ein weiterer Punkt, der für die Verwendung von 3D-Druckern sprechen, sind ihre geringen Anschaffungskosten. Bereits für ab 200€ sind Bausätze für kleine Drucker auf dem Markt, welche aber eher als Spielerei zu betrachten sind. Jedoch kann man ab etwa 1000€ einen Bausatz für einen ernstzunehmenden 3D-Drucker des OpenSource-Projekts RepRap erhalten, welcher auch beim Projekt Daedalus zum Einsatz kommt:

 

 

 

 

 

Auch die Instandhaltungs- und Rohstoffkosten sind nicht erheblich, da eine Rolle an Kunststoff etwa 50€ kostet, mit der man durchaus einiges drucken kann, und oft (zumindest beim Modell von RepRap) lassen sich Ersatzteile auch durch den Drucker selbst anfertigen.

Was beim ersten Anblick vielleicht als eine gute Sache wirkt, ist bei näherer Betrachtung ein entscheidender Nachteil von solch güstigen Modellen: sie sind klein und meist damit auch sehr leicht. Zwar kann man sie so nahezu überall unterbringen und es ist auch kein Akt sie von einem Ort zum nächsten zu bewegen, jedoch haben sie das Problem, dass der Rahmen bei schnellen Bewegungen des Extruderschlitten zum schwingen anfängt und somit der gesamte Druck unschöne Wellenmuster oder unsaubere Kanten bekommt, bis hin zu unbrauchbaren Ergebnissen bei filigranen Modellen.

Im Rahmen meiner 5-wöchigen Ingenieurspraxis soll nun der bereits erwähnte 3D-Drucker von RepRap mit Sensoren ausgestattet werden, um Rückschlüsse über den Druckvorgang zu erhalten und durch das Prinzip des Maschinellen Lernens den Druckvorgang zu verbessern, damit die Schwingungen des Rahmens minimiert werden können.
Des weiteren soll ein Temperatursensor am Extruderkopf installiert werden, um dessen Temperatur zu messen und zu Protokollieren. In einem Weiterführenden Schritt kann dann auch die Temperatur mit diesem Ergebnis gesteuert werden.

Hierbei soll aber der Aufbau des Druckers (bis auf die Anbringung der Sensoren) unverändert bleiben und nur auf den mit dem Programm Slic3er erstellte GCode einfluss genommen werden, damit die erhaltenen Informationen und Lösungsmöglichkeiten gegen die Schwingungen auch an weiteren, durchaus auch an anders aufgebauten Druckern, angewendet werden können.

Hardware

Beschleunigungssensoren

Für das Maschinelle Lernen werden die Beschleunigungsdaten des Extruderschlittens (die Beschleunigung, auf die Einfluss genommen werden kann), des Rahmens (diejenige, die minimiert werden soll) und des Tisches, auf dem der Drucker steht (um äußere Einflüsse herausrechnen zu können) benötigt. Deshalb werden, wie in folgender Schematik verdeutlicht, die genannten drei Sensoren angebracht:

[Schematik mit Aufbau der Sensoren]

Zum Einsatz kommen hierbei Sensoren mit der Modellnummer MMA8452Q, bezogen von Sparkfun. Diese sind kostengünstig, liefern Messdaten auf allen drei Achsen und bieten die benötigte Auflösung von ±2g bis ±8g und Genauigkeit für diese Anwendung. Da die Breakout-boards unverhältnismäßig teuer sind, wurden diese selbst gelötet:

Dies war ein recht schweres Unterfangen, da die Lötpads nur etwa 0.3mm x 0.5mm groß sind, und die hierfür benötigten Kupferlackdrähte sehr leicht brechen. Deshalb wurden die Drähte nach dem Löten mit einem Tropfen Kunstharz befestigt. Ausserdem wurden die Sensoren für den Rahmen und den Tisch auf einer extra Platine befestigt. Wie auf folgendem Boardlayout und Schaltplan zu erkennen ist, werden alle Anschlüsse nach aussen hin zu einem 6fach-Pinheader geführt:

[Plan von den Sensorplatinen + Layout mit beschriftung was wo is]

Da aber bei der Optimierung des Druckvorgangs nicht alle Anschlüsse (zum beispiel INT1 und INT2) benötigt werden, wurden diese einfach nicht mit einem Anschlussdraht versehen, können jedoch für die Zukunft leicht nachgerüstet werden.

Zu großen Belastungen sollten die Sensoren und die Lötstellen dennoch nicht ausgesetzt werden, weshalb bei einem Umzug auf einen anderen Drucker oder an andere Stellen am Drucker besonders acht gegeben werden sollte.

Angesprochen werden die Sensoren auf dem I²C-Bus, wobei dies zu einem Zusätzlichen Problem führt: die Sensoren unterstützen nur zwei verschiedene Adressen. Da aber drei benötigt werden, wurde ein Ansatz über zwei I²C-Linebuffer gewählt, wobei immer einer An- und der andere Abgeschaltet wird, damit auf einer Adresse somit letztlich zwei Sensoren liegen können.

 

Temperatursensor

Als Temperatursensoren werden Platin-Widerstandsthermoeter PT1000 verwendet. Charakteristisch für sie sind der steigende Widerstand bei steigender Temperatur, wobei eine lineare Proportionalität vorliegt. Dies macht es einfacher, auf den Widerstand und somit auf die Temperatur in einer Schaltung zurückzuschließen.

Für die Messung des Widerstandes muss zunächst die an ihm abfallende Spannung gemessen werden, wozu eine Konstantstromquelle benötigt wird. Diese wird durch eine einfache Transistorschaltung realisiert. Ein positiver Nebeneffekt einer Konstantstromquelle ist, dass man einen ziemlich geringen Strom einstellen kann, wodurch sich die Eigenerwärmung des Temperatursensors in Grenzen hält.

Der konstante Strom speist dann eine Wheatstone-Brückenschaltung, in welcher sich der Sensor auf der linken Seite befindet. Auf der rechten Seite ist ein Potentiometer zum Abgleich und Justierung der Werte angebracht.

Die in der Wheatstone-Brücke abfallende Spannung wird abschließend noch durch einen Differenzverstärker mit dem Verstärkungsfaktor [??] geschickt,

Sensor-Shield

Da alle Sensoren noch weitere Bauteile benötigen, zum Beispiel die I²C-Linebuffer zum Sensorwechsel oder die Messbrücke für den Temperatursensor, habe ich ein kleines Shield für den selbstgefrästen Arduino erstellt. Er beherbergt alle nötigten Bauteile und wird einfach auf die Pinheader des Arduinos aufgesteckt. Damit der ICSP-Header des Arduinos auf dem Shield keine Kurzschlüsse verursacht, muss ein stück Klebeband (oder ähnlich festes) dazwischengeklemmt werden.

[Circuit + Bild]

Ein kleines Problem bei der Konstruktion solcher Boards sind die eigentlich dafür benötigten Pinheader mit langen Füßen, welche speziell für diese Vorhaben erhältlich sind. Jedoch sind diese ziemlich teuer, weshalb ich mich dazu entschlossen habe, Parallel zu den aufgesetzten Female-Pinheadern noch Male-Pinheader, welche nach unten gerichtet sind, anzulöten, wodurch einige Euro gespart werden konnten.

Microkontroller

Für den Steuernden und Datenverarbeitenden Microkontroller wurde ein selbstgefräster Arduino Duemilanove mit einem Atmel ATmega328 als IC verwendet. Prinzipiell ist die Verwendung eines jeden Arduino Duemilanoves oder Unos möglich, jedoch muss dann ein Adapter für das Sensor-Shield verwendet werden, welcher die jeweiligen Ports miteinander verbindet, da beim selbstgefrästen Arduino die Aufteilung der Ports auf den Pinheadern anders ist.

Software

Datenlogger

[Skriptschematik]

Der Datenlogger ist ein selbstgeschriebenes Pythonskript, welches zur Aufgabe hat, auf die GCodes zu protokollieren sowie die Sensordaten des Arduinos entgegenzunehmen und dies gesammelt CSV-Dateien zu schreiben, damit sie anschließend zum Beispiel in Matlab ausgewertet werden können.

Damit das restliche Programm für den Drucker nicht unnötigt mit Dateioperationen gestört wird, wird ein eigener Thread erzeugt, welcher sich ausschließlich darum kümmert, Datensätze aus einer Queue zu lesen und diese in die CSV datei zu schreiben. Auch war geplant, in einem separaten Thread die Sensordaten über eine serielle Verbindung vom Arduino entgegenzunehmen. Leider ist jedoch der Rechner, auf dem das Skript arbeitet und welcher den Drucker steuert relativ langsam, weshalb nun der Skriptteil, welcher die Sensoren ausliest, auf einen externen Computer ausgelagert wird. Ausserdem wurde in der Datei printcore.py in der Funktion _send eine Zeile eingefügt, um die GCodes, die das Pronterface an den Drucker sendet, weiterzuleiten, damit diese vom Datenlogger mitgeschnitten werden können.

Damit die GCodes durch die Auslagerung immer noch den passenden Beschleunigungsdaten zugewiesen werden können, synchronisiert sich das Skript vor dem Start mehrmals mit einem Zeitserver des LRZ. Sollte jedoch der Computer des Druckers einmal aufgewertet werden, kann das Gesamtskript nach wie vor als Einheit gestartet werden. Dazu muss vor dem Aufruf der Datei printcore.py der Sensor-Arduino am höchsten USB-Port angeschlossen sein. Findet das Skript diesen, startet es automatisch die Sensorverarbeitung mit. Alternativ kann der Code in der Funktion __init__ dahingehend angepasst werden, dass nichtmehr der höchste verbundene USB-Port, sondern eben der, auf dem der Arduino angeschlossen ist, verwendet wird. Sollen nur die Sensordaten verarbeitet werden, also die GCodes ignoriert werden (zum Beispiel eben auf dem externen Rechner), so muss das Skript über python DatenLogger.py gestartet werden.

Eingriffe in das Pronterface

Damit die GCodes des Druckers mitgeschnitten werden können, mussten in der Datei printcore.py ein paar Zeilen Code hinzugefügt werden:

Funktion _send() (Zeile 367f):

if self.data_logger:
    self.data_logger.queueCode(command)

Funktion __init__() (Zeile 72):

self.data_logger = DataLogger.DataLogger()

Funktion disconnect() (Zeile 90f):

if self.data_logger:
    self.data_logger.endLogging()

Funktion pause() (Zeile 237f):

if self.data_logger:
    self.data_logger.pauseLogging()

Funktion resume() (Zeile 247):

if self.data_logger:
    self.data_logger.resumeLogging()

Funktion _print() (Zeile 297):

self.data_logger.startLogging()

Funktion _print() (Zeile 311f):

if self.data_logger:
    self.data_logger.endLogging()

 

Arduino-Programm

Das Arduino-Programm befindet sich im Anhang. Es besteht aus zwei Teilen: einem zum Einlesen der Spannungen, welche die Messbrücke des Temperatursensors liefert und deren Umrechnung in die jeweilige Temperatur, und der Teil zum Auslesen und Auswerten der Daten der Beschleunigungssensoren.

Um die Beschleunigungsdaten festzustellen, werden, sobald vom Pyhton-Skript das Signal zum senden der Sensorwerte gesendet wurde, alle Beschleunigungssensoren nacheinander Abgefragt durch direktes Auslesen der Register und Umrechnen mit der jeweiligen gesetzten Genauigkeit. Anschließend werden diese Daten über die Serielle Verbindung (per USB) an den Computer gesendet. Hierbei werden die Sensoren 2 und 3 (Rahmen und Tisch) nur abwechselnd ausgelesen, indem der jeweilige I²C-Linebuffer aktiviert und der andere Deaktiviert wurde, womit nur einer der Sensoren mit dem Arduino verbunden ist.

Für die Temperaturmessung werden die vom OpAmp gelieferten Spannungswerte auf dem Analog-Port 3 ausgelesen und mit Hilfe der Formeln für die Messbrücke wieder auf den vorliegenden derzeitigen Widerstandswert des PT1000 zurückgerechnet, womit direkt auf die Temperatur geschlossen werden kann. Da eine gewisse Nichtlinearität vorliegt, werden die Spannungswerte noch mit einer Funktion interpoliert. Um die Werte des Polynoms zur Interpolation festzustellen, mussten die Widerstandswerte mit einem Multimeter und dessen Messfunktion abgeglichen werden.

Anleitungen

Datenlogging

  1. Pronterface auf dem Drucker-Computer im Ordner printer_sensor (sollte auf dem D esktop liegen) über den Befehl python pronterface.py starten.
  2. Arduino Duemilanove oder Uno mit montiertem Sensorshield und korrekt angeschlossenen Sensoren mit dem Datenlogger-Computer verbinden. Der Arduino muss auf dem höchsten Port liegen, ansonsten in der Datei DatenLogger.py in der Funktion __init__() die Zeile self.arduinoPort auf den Wert "/dev/ttyUSBX" (mit Anführungszeichen) setzen, wobei X mit dem verbundenen Port ersetzt wird.
  3. Auf dem Datenlogger-Computer das Skript aus dem Ordner printer_sensor über python DatenLogger.py starten. Dort werden dann nur die Sensordaten erfasst.
  4. Ist der Druckvorgang beendet oder soll das Skript mittdendrin beendet werden, dann sollte dies über die Tastenkombination "STRG+C" erfolgen. Damit wird sichergestellt, dass alle zwischengespeicherten Werte noch fertig geschrieben werden.

Fehlerbehebung

  • "[DataLogger] Could not connect to arduino! Not on highest USB-Port?" Stelle sicher, dass der Arduino mit dem höchsten USB-Port verbunden ist bzw. ändere dies gemäß der Anleitung Punkt 2. Ausserdem sollte überprüft werden, ob die richtige Software auf den Arduino geflasht wurde und ob das Shield bzw. die Sensoren richtig verbunden sind.
  • "[DataLogger] Could not connect to arduino!" Stelle sicher, dass auf den Arduino die richtige Software geflasht wurde und dass die Sensoren sowie das Shield richtig angeschlossen sind. Die gelbe LED auf dem Arduino muss leuchten, sobald er über USB verbunden ist. Ist dies nicht der fall, liegt höchst wahrscheinlich ein Kurzschluss vor, zum Beispiel hervorgerufen durch falsche Polung der Sensoren.
  • "" Dies passiert, wenn der Arduino nicht mehr seine Dauerschleife aufruft, sondern stehen bleibt. Überprüfe, ob alle drei Beschleunigungssensoren (vor allem der am Extruder!) fest verbaut sind und auch, ob der Stecker sicher angeschlossen sind. Tritt das Problem öfter auf, sollten die Sensoren abmontiert und die Lötstellen am Sensor sowie an der Platine der Kupferdrähte überprüft werden. Diese können sich leicht lösen bzw. brechen, weshalb es sein kann, dass diese Nachgelötet werden müssen. Hilft auch das nichts, kann testweise im Programmcode vom Arduino die Verzögerungszeit zum Auslesen der Werte auf einen höheren Delay-Wert gesetzt werden (letzte Zeile in der loop-Funktion). Es kann auch helfen, mit dem Datenlogger-Skript auf einen schneller arbeitenden Computer umzuziehen. Generell sollte überdacht werden, die Sensoren in Zukunft auf geäzten Boards fest zu verlöten, statt sie über Kupferlackdrähte zu verbinden.