Einfach praktisch ist er schon, der 3D-Drucker. Ein Kunststoff-Filament bis zum flüssigen Zustand erwärmen und mit einem Drei – Achsen – Positionierer den Kunststoff schichtweise auftragen. Das ist ganz das grob beschriebene Prinzip eines 3D-Druckers. Und mit genauso einem Drucker habe ich schlussendlich das hier beschriebene Objekt ausgedruckt. Bei dem verwendeten Drucker handelt es sich um einen Ultimaker 2+, der mit ABS-Filament mit 2.85mm Durchmesser als Druckmedium befüllt ist.
Doch vor dem Ausdrucken muss erst einmal ein Druckmodell her. Hier gibt es im Netz eine Vielfalt an fertigen herunterladbaren Modellen, die direkt gedruckt werden können. Eine Website ist hier zum Beispiel thingiverse. Hier können die Community – Mitglieder ihre Designs und Objekte veröffentlichen und frei zugänglich machen. Doch ich wollte kein fertiges Modell nehmen, sondern den gesamten Designflow einmal von Beginn an durchmachen und testen, ob die, hier bei uns in der Arbeit verwendeten Tools auch zuverlässig funktionieren. Für dieses Testobjekt, einen Telefonaufsteller – oder „Handyhalter“ habe ich folgende Tools verwendet:
Die 3D – Konstruktion habe ich mit AutoCad 2013 von Autodesk gezeichnet. Hier kamen einfach nur 3D Körper wie Quader und Zylinder zum Einsatz, die durch Addition, Subtraktion und extrudieren von Objekten das gewünschte Ergebnis liefern. Das fertige Objekt wird dann als Stereo-Lithografie-Datei (.stl) exportiert.
Jetzt kommt die sogenannte Slicer – Software zum Einsatz. Slicer bedeutet sinngemäß so viel wie zerschneiden, aufschneiden. Und nichts anderes macht diese Software. Das dort geladene Druckmodell wird in Schichten zerlegt, so wie sie der Drucker später auch als Kunststoffebene schichtenweise aufträgt. Auch hier gibt es einiges an open-source und freeware Software. Ich habe Cura verwendet. Dieses Slicer-Tool wird auch von Ultimaker angeboten und kann auch direkt mit deren Hardware arbeiten. Im Slicer werden dann einige Parameter festgelegt, die für den Druck dann wichtig sind. Das sind die Temperatur auf die das Filament erwärmt wird, die Plate Temperatur, die Materialvorschubgeschwindigkeit (ist abhängig von der Druckdüse und dem Material selbst), die Druckgeschwindigkeit usw. Hier sind etliche Dinge zu beachten und definieren, die schlussendlich erhebliche Auswirkung auf die Qualität, den Materialverbrauch und die Druckzeit haben…
Heute stelle ich kurz ein Miniprojekt, das aus gegebenem Anlass entstanden ist, vor. Zum Thema 3D-Druck mit dem Ultimaker 2 Drucker gibt es ja mittlerweile schon tonnenweise Informationen im Web. Auch die Steuerung über einen Webserver (octoprint) samt Webkamera Überwachung ist sehr gut dokumentiert und einfach zu realisieren. So haben es viele selbsternannte 3D-Drucker-Experten einfach, und können auf das umfangreiche Wissen aus dem Web zurückgreifen. An meinem Arbeitsplatz im Labor ist seit kurzem auch ein Ultimaker 2+ Drucker im Einsatz und wird, da ja viele Druckaufträge oft mehrere Stunden bis zur Vollendung benötigen, per Webcam überwacht. Jetzt könnte man den Drucker unbeaufsichtigt drucken lassen und den Raum oder das Gebäude verlassen und den Fortschritt remote überwachen. Doch wenn jetzt etwas nicht nach Plan verläuft und der Druckkopf beispielsweise mit dem Druckobjekt kollidiert oder das Druckobjekt selbst nicht so gedruckt wird, wie es der Slicer vorsieht, dann kann der Drucker nicht per Remote not-abgeschaltet werden.
Da der Octoprint – Server nun aber auf einem Raspberry PI läuft, dessen GPIO Port – Pins einfach ungenutzt herumstehen :), bieten sich diese an, ein Interface zu bauen, das im Falle des Falles die Stromversorgung des Druckers abschalten kann. Eine, in ein kleines Kunststoffgehäuse eingebaute Relaisplatine soll an die GPIOs angeschlossen werden. Die Relaiskontakte werden dann daran angeschlossene Schuko Steckdosen schalten. Ich habe die Relaisplatine für vier Kanäle dimensioniert, um nicht nur den Drucker notabschalten zu können, sondern zukünftig auch ein Abluftventilator etc. damit zu schalten. Die Schaltbefehle werden dann direkt am Raspberry, über z.B. Python-Skripten, oder einfach nur bash Kommandos ausgeführt.
Hier ist die supereinfache Schaltung für den Aufbau der Relaiskarte dargestellt:
Vom Papier zur fertigen Platine und diese dann in ein Gehäuse eingebaut und per 40poliger Stiftleiste und Flachbandkabel an den Raspberry PI angesteckt, ist im folgenden Bild zu sehen. Als Geräte Bezeichnung ist mir „Ultimaker Schuko Controller“ eingefallen. Da die Aluminium-Frontplatte des Gehäuses wegen der Aussparung für das Flachbandkabel ohnehin in den Fräsbohrplotter musste, habe ich den Schriftzug „Ultimaker Schuko Controller“ auch gleich dort verewigt.
Die Hardware ist nun fertig und mit dem Raspberry verbunden. Als GPIO Pins habe ich, wie im Schaltplan zu erkennen, die GPIOs 08, 23, 24 und 25 verwendet. Als einfachen Test kann man die Relais jetzt über das Terminalfenster des Raspberry (entweder lokal, oder über einen Putty) ganz einfach ansteuern. Als Beispiel ist hier GPIO Pin8 angegeben:
In einem früheren Blogeintrag habe ich einen Uhrenbausatz vorgestellt, dessen Anzeigenelemente mit VFD-Röhren aufgebaut sind. Diese Vakuum-Fluoreszenz-Display Röhren stammen, wie auch die Nixieröhren, aus den 60iger, 70iger Jahren und wurden dann von den LED 7-Segment Anzeigen abgelöst. Doch der Reiz der glimmenden, in Glaskolben verpackten Leuchtziffern erobert heute wieder so manches Wohnzimmerregal. Über den damaligen Beitrag über den VFD – Uhrenbausatz von gr-projects, bin ich mit dem Konstrukteur und Hersteller dieses Bausatzes, Herrn Rother in Kontakt gekommen. Herr Rother hat mir weitere Uhrenmodelle zur Verfügung gestellt, deren Auf- und Zusammenbau ich in Form kurzer Filme aufbereitet und dokumentiert habe. Die verwendeten Anzeigeröhren sind russische Röhren der Typen IV-11, IV-6 und IV-3.
Hier die Infos zu den Röhren:
IV-11:
Glaskolben mit einer Höhe von 55mm und einem Durchmesser von 22mm.
Anzeigehöhe 20x13mm (HxB)
Heizspannung 1,5V bei einem Strom von 50-70mA
Gitterspannung ca 25-30V
Lebensdauer ca. 5000h
IV-6:
Glaskolben mit einer Höhe von 40mm und einem Durchmesser von 12mm.
Im letzten Teil des Projektes „Raspberry Pi als Datenlogger“ habe ich einen Raspberry Pi als Datenlogger für unterschiedliche Sensoren konfiguriert. Als Schnittstelle dient der I²C Bus und die RS232 Leitungen, an denen die Sensoren angeschlossen sind. Die Sensoren waren ein HYT939 (Luftfeuchtigkeit und Temperatur), ein BME280 (Luftdruck, Luftfeuchte und Temperatur) sowie ein Ultimate GPS Board an der seriellen Schnittstelle. Der Raspberry Pi ist dabei in eine Box eingebaut, wird mit einer Powerbank, die sich ebenfalls in der Box befindet, versorgt und stellt als Schnittstelle eine 8 polige RJ45 Buchse mit I²C und RS232 nach außen zur Verfügung. An diese Buchse können dann die Sensoren angeschlossen werden. Will man die Sensorik nun ändern, bzw. erweitern, so können einfach weitere I²C Bus – Sensoren angeschlossen werden. Es muss lediglich noch die Software (in diesem Fall Python Skripten) angepasst werden und schon können die Daten des neuen Sensors empfangen und aufgezeichnet werden. Wie aber geht das System um, wenn der Sensor nicht über I²C spricht? Wenn zum Beispiel ein analoger Wert eingelesen werden soll? Ganz einfach: Soll die Hardware des Datenloggers nun nicht mehr modifiziert werden, so muss man einfach dafür sorgen, dass der neue Sensor, der beispielsweise analoge Spannungen ausgibt, diese an eine, nennen wir sie Black Box weitergibt, die wiederum an ihrem Ausgang ein I²C Bussignal bereit stellt. Das kann dann wieder in das bestehende System integriert werden.
Und genau diese Aufgabe erfüllt ein Microcontroller. Praktischer Weise habe ich diesmal einen Arduino Nano dazu verwendet. Der Arduino Nano mit dem Atmega 328 besitzt ja mehrere analoge und Digitale Eingänge, sowie zwei Interrupts. Über entsprechende Libraries ist einfach das I²C Bus Protokoll zu realisieren. Somit ist das geeignete Black-Box Gerät gefunden.
Der folgende Arduino Code stellt einen einfachen I²C Bus Slave dar. Die Busadresse soll beispielsweise 0x08 sein, von einer Messung haben wir den Messwert 1.3321 erhalten. Dieser Wert soll bei Anfrage an diese Busadresse gesendet werden. Das Beispiel sieht wie folgt aus:
Im Skript ist eine Funktion „dtostrf“ zu sehen. Sie wandelt den Inhalt einer Variablen des Datentyps „floating point“ in ein Charakter Array um. Infos sind hier zu sehen. Im Python Interpreter des Raspberry können wir nun überprüfen, ob die Daten ankommen. Doch zuvor soll der gesamte Aufbau einmal schematisch dargestellt werden.
Sind alle Sensoren inklusive des Arduino angeschlossen, so kann das folgende Python-Skript aus der Linux Konsole des Raspberry aufgerufen werden:
# Reading data from arduino as sensor slave
# V0.1 by bihlo 09/2016
import smbus, time
bus = smbus.SMBus(1) # Raspberry Rev. 2
address = 0x08 # Fixed default address of Arduino
# Initialize sensor to acquire measurements
#def MeasurementRequest():
# void = bus.write_quick(address)
#time.sleep(0.1)
# Read from bus
def ReadMeasurement():
void= bus.write_quick(address)
time.sleep(0.1)
# Acquire 6 byte from sensor
Readout = bus.read_i2c_block_data(address,0,6)
out=''.join(chr(i) for i in Readout) #byte array von ascii in string wandeln
print "Antwort vom Arduino: ", Readout, " ."
print "Antwort als String: ", out
ReadMeasurement()
Wenn der Python Interpreter jetzt keinen Fehler meldet und der Inhalt der Variable „wert“ des Arduino in ASCII und im Klartext dargestellt wird, dann kann jetzt mit einem „richtigen“ Messwert eines Sensors weiter gearbeitet werden.
Als Sensor soll an an den Arduino ein DSM501 Dust Sensor Module angeschlossen werden. Der DSM501A ist ein Staubsensor, der mit 5V bei einer Stromaufnahme von 90mA betrieben wird. Er erkennt Partikel ab einer durchschnittlichen Größe von 1µm bei einer Konzentration von 0 bis ca. 1.4mg pro Kubikmeter Raumluft. Laut Datenblatt und Herstellerinformationen wird die Luft im Bereich der Messkammer erhitzt, sodass eine Luftzirkulation entsteht. Die sich ständig bewegende Luft wird mit einem getakteten Lichtstrahl beleuchtet. Ein in einem Winkel zur Lichtquelle angebrachter Fotodetektor empfängt nun, im Falle dass sich Partikel im Licht befinden, dessen Streulicht. Die Intensität des Streulichtes ist von der Anzahl und Größe der Partikel abhängig und kann so erfasst werden. Als Ausgangssignal erzeugt der Sensor ein Puls/Pausensignal mit einer Periode von 100ms. Das Verhältnis von High- zu Lowtime stellt nun die Grundlage für die Berechnung der Partikelanzahl bzw. -dichte dar. Über einen Countereingang des Arduino werden die Impulse gemessen und der korrespondierende Partikelwert errechnet. Dieser Wert wird nun wie oben beschrieben als Busdatum für den I2C Bus herangezogen und bei Auslösen des Bus Events übertragen. Somit hat der Arduino die Aufgabe eines einfachen Protokollkonverters übernommen. Mit dieser Methode lassen sich alle möglichen Messwerte so aufbereiten, dass der Raspberry mit einer Schnittstelle damit umgehen kann.
Wie das im Detail funktioniert und wie der Code dazu aussieht, werde ich vielleicht später einmal posten.